diff --git a/.drone.yml b/.drone.yml
index 6f52ca3..f467229 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -3,40 +3,105 @@ kind: pipeline
name: default
steps:
- - name: weblinks-codeception-tests
- image: joomlaprojects/docker-images:systemtests
+ - name: composer
+ image: joomlaprojects/docker-images:php8.2
+ volumes:
+ - name: composer-cache
+ path: /tmp/composer-cache
commands:
- - pwd
- - composer install
- - chmod a+x .drone/build.sh
- - ./.drone/build.sh
- - apache2ctl start
- - service mysql start
- - cd /tests/www
- - export DISPLAY=:0
- - Xvfb -screen 0 1024x768x24 -ac +extension GLX +render -noreset > /dev/null 2>&1 &
- - sleep 3
- - fluxbox > /dev/null 2>&1 &
- - vendor/bin/robo run:tests
+ - composer install --no-progress
- - name: artifacts-codeception-tests
- image: cschlosser/drone-ftps
- depends_on: [ weblinks-codeception-tests ]
+ - name: phpcs
+ image: joomlaprojects/docker-images:php8.1
+ depends_on: [ composer ]
+ commands:
+ - echo $(date)
+ - ./vendor/bin/php-cs-fixer fix -vvv --dry-run --diff
+ - ./vendor/bin/phpcs --extensions=php -p --standard=ruleset.xml src/
+ - echo $(date)
+
+ - name: npm
+ image: node:16-bullseye-slim
+ depends_on: [ phpcs ]
+ volumes:
+ - name: npm-cache
+ path: /tmp/npm-cache
+ environment:
+ npm_config_cache: /tmp/npm-cache
+ commands:
+ - npm i --unsafe-perm
+
+ - name: prepare_system_tests
+ depends_on: [ npm ]
+ image: joomlaprojects/docker-images:systemtests
+ volumes:
+ - name: cypress-cache
+ path: /root/.cache/Cypress
+ commands:
+ - mv cypress.config.dist.js cypress.config.js
+ - npx cypress install
+ - npx cypress verify
+ - vendor/bin/robo build
+ - curl https://joomla.org/latest -L --output joomla.zip
+ - mkdir joomla
+ - cp joomla.zip joomla/joomla.zip
+ - cd joomla
+ - unzip joomla.zip
+
+ - name: phan
+ image: joomlaprojects/docker-images:php8.1-ast
+ depends_on: [ prepare_system_tests ]
+ failure: ignore
+ commands:
+ - vendor/bin/phan
+
+ - name: phpstan
+ image: joomlaprojects/docker-images:php8.1
+ depends_on: [ prepare_system_tests ]
+ failure: ignore
+ commands:
+ - vendor/bin/phpstan analyse src
+
+ - name: phpmin-system-mysql
+ depends_on: [ prepare_system_tests ]
+ image: joomlaprojects/docker-images:cypress
+ volumes:
+ - name: cypress-cache
+ path: /root/.cache/Cypress
+ commands:
+ - mkdir /tests/www/mysql/
+ - cp joomla.zip /tests/www/mysql/joomla.zip
+ - cp dist/pkg-weblinks-current.zip /tests/www/mysql/pkg-weblinks-current.zip
+ - cd /tests/www/mysql/
+ - unzip joomla.zip
+ - apache2ctl -D FOREGROUND &
+ - chmod +rwx /root
+ - php installation/joomla.php install --verbose --site-name="Joomla CMS test" --admin-email=admin@example.org --admin-username=ci-admin --admin-user="jane doe" --admin-password=joomla-17082005 --db-type=mysqli --db-host=mysql --db-name=test_joomla --db-pass=joomla_ut --db-user=root --db-encryption=0 --db-prefix=mysql_
+ - php cli/joomla.php config:set debug=true error_reporting=maximum
+ - php cli/joomla.php extension:install --path=/tests/www/mysql/pkg-weblinks-current.zip
+ - chmod -R 777 /tests/www/mysql/
+ - chown -R www-data /tests/www/mysql/
+ - cd /drone/src
+ - npx cypress run --browser=firefox --e2e --config baseUrl=http://localhost/mysql,screenshotsFolder=/drone/src/tests/cypress/output/screenshots
+
+ - name: artifacts-system-tests
+ image: joomlaprojects/docker-images:packager
+ depends_on:
+ - phpmin-system-mysql
environment:
FTP_USERNAME:
from_secret: ftpusername
FTP_PASSWORD:
from_secret: ftppassword
- PLUGIN_HOSTNAME: artifacts.joomla.org:21
- PLUGIN_SRC_DIR: /tests/_output
- PLUGIN_DEST_DIR: /
- PLUGIN_SECURE: false
- PLUGIN_EXCLUDE: ^\.git/$
+ GITHUB_TOKEN:
+ from_secret: github_token
commands:
- - ls -l /drone/src/tests/_output
- - export PLUGIN_DEST_DIR=$PLUGIN_DEST_DIR/$DRONE_REPO/$DRONE_BRANCH/$DRONE_PULL_REQUEST/system-tests/$DRONE_BUILD_NUMBER
- - echo https://artifacts.joomla.org/drone$PLUGIN_DEST_DIR
- - /bin/upload.sh
+ - export PLUGIN_DEST_DIR=/artifacts/$DRONE_REPO/$DRONE_BRANCH/$DRONE_PULL_REQUEST/system-tests/$DRONE_BUILD_NUMBER
+ - echo https://ci.joomla.org$PLUGIN_DEST_DIR
+ - rclone config create artifacts ftp host ci.joomla.org user $FTP_USERNAME port 21 pass $FTP_PASSWORD
+ - rclone mkdir artifacts:$PLUGIN_DEST_DIR
+ - rclone copy tests/cypress/output/ artifacts:$PLUGIN_DEST_DIR
+ - 'curl -X POST "https://api.github.com/repos/$DRONE_REPO/statuses/$DRONE_COMMIT" -H "Content-Type: application/json" -H "Authorization: token $GITHUB_TOKEN" -d "{\"state\":\"failure\", \"context\": \"Artifacts from Failure\", \"description\": \"You can find artifacts from the failure of the build here:\", \"target_url\": \"https://ci.joomla.org$PLUGIN_DEST_DIR\"}" > /dev/null'
when:
status:
- failure
@@ -45,9 +110,45 @@ volumes:
- name: weblinks_cache
host:
path: /tmp/weblinks_cache
+ - name: composer-cache
+ host:
+ path: /tmp/composer-cache
+ - name: cypress-cache
+ host:
+ path: /tmp/cypress-cache
+ - name: npm-cache
+ host:
+ path: /tmp/npm-cache
+
+services:
+ - name: mysql
+ image: mysql:5.7
+ environment:
+ MYSQL_USER: joomla_ut
+ MYSQL_PASSWORD: joomla_ut
+ MYSQL_ROOT_PASSWORD: joomla_ut
+ MYSQL_DATABASE: test_joomla
+
+ - name: mysql8
+ image: mysql:8
+ command: ["--default-authentication-plugin=mysql_native_password"]
+ environment:
+ MYSQL_USER: joomla_ut
+ MYSQL_PASSWORD: joomla_ut
+ MYSQL_ROOT_PASSWORD: joomla_ut
+ MYSQL_DATABASE: test_joomla
+
+ - name: postgres
+ image: postgres:11-alpine
+ ports:
+ - 5432
+ environment:
+ POSTGRES_USER: root
+ POSTGRES_PASSWORD: joomla_ut
+ POSTGRES_DB: test_joomla
---
kind: signature
-hmac: bcc028d5d9601f1f3355862f17dd2434ba86f47634f0737877db534e49c8265b
+hmac: 8b2b4e6fe85da897755c46d961b49c1e53a13e5a2cf6df5cde70aa07233b2494
...
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..dd23145
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,20 @@
+# EditorConfig is awesome: https://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+# Unix-style end of lines and a blank line at the end of the file
+[*]
+indent_style = tab
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.php]
+indent_style = space
+indent_size = 4
+
+[*.{js,json,scss,css,yml,vue}]
+indent_style = space
+indent_size = 2
diff --git a/.gitignore b/.gitignore
index 206a30d..f7f9767 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,64 +1,73 @@
-# Builds
-build
-releases
-
-# OSX
-.DS_Store
-._*
-.Spotlight-V100
-.Trashes
-
-# Windows
-Thumbs.db
-Desktop.ini
-
-# PHPStorm
-.idea/
-
-# Sublime Text
-*.sublime*
-
-# Eclipse
-.buildpath
-.project
-.settings
-
-# Temp files
-*.tmp
-*.bak
-*.swp
-*~.nib
-*~
-
-# Phing
-build.properties
-phing-latest.phar
-
-# Github pages and Jekyll files
-/_site/
-/Gemfile
-/Gemfile.lock
-
-# composer
-composer.phar
-vendor/*
-
-# Robo
-robo.phar
-RoboFile.ini
-
-# Test related files
-tests/acceptance.suite.yml
-tests/*/*Tester.php
-tests/_support/_generated/*TesterActions.php
-tests/joomla*
-tests/_output*
-selenium-server-standalone.jar
-codecept.phar
-selenium.log
-tests/cache
-
-# Package building related
-/dist
-jorobo.ini
-
+# Builds
+build
+releases
+
+# OSX
+.DS_Store
+._*
+.Spotlight-V100
+.Trashes
+
+# Windows
+Thumbs.db
+Desktop.ini
+
+# PHPStorm
+.idea/
+
+# Sublime Text
+*.sublime*
+
+# Eclipse
+.buildpath
+.project
+.settings
+
+# Temp files
+*.tmp
+*.bak
+*.swp
+*~.nib
+*~
+
+# Phing
+build.properties
+phing-latest.phar
+
+# Github pages and Jekyll files
+/_site/
+/Gemfile
+/Gemfile.lock
+
+# composer
+composer.phar
+vendor/*
+
+# Robo
+robo.phar
+RoboFile.ini
+
+# Test related files
+tests/acceptance.suite.yml
+tests/*/*Tester.php
+tests/_support/_generated/*TesterActions.php
+tests/joomla*
+tests/_output*
+selenium-server-standalone.jar
+codecept.phar
+selenium.log
+tests/cache
+
+#cypress
+node_modules
+/tests/cypress/output/screenshots
+!/tests/cypress/output/screenshots/.gitkeep
+/tests/cypress/output/videos
+!/tests/cypress/output/videos/.gitkeep
+cypress.config.js
+joomla
+
+# Package building related
+/dist
+jorobo.ini
+
diff --git a/.phan/config.php b/.phan/config.php
index 33f9693..bda9b76 100644
--- a/.phan/config.php
+++ b/.phan/config.php
@@ -291,7 +291,8 @@ return [
// should be added to the `directory_list` as well as
// to `exclude_analysis_directory_list`.
'exclude_analysis_directory_list' => [
- 'tests/joomla'
+ 'joomla/administrator/components/com_finder/src/Indexer',
+ 'joomla/libraries'
],
// Enable this to enable checks of require/include statements referring to valid paths.
@@ -338,7 +339,8 @@ return [
// your application should be included in this list.
'directory_list' => [
'src',
- 'tests/joomla'
+ 'joomla/administrator/components/com_finder/src/Indexer',
+ 'joomla/libraries'
],
// A list of individual files to include in analysis
diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php
new file mode 100644
index 0000000..a658ca5
--- /dev/null
+++ b/.php-cs-fixer.dist.php
@@ -0,0 +1,67 @@
+
+ * @license GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+/**
+ * This is the configuration file for php-cs-fixer
+ *
+ * @see https://github.com/FriendsOfPHP/PHP-CS-Fixer
+ * @see https://mlocati.github.io/php-cs-fixer-configurator/#version:3.0
+ *
+ *
+ * If you would like to run the automated clean up, then open a command line and type one of the commands below
+ *
+ * To run a quick dry run to see the files that would be modified:
+ *
+ * ./component/backend/vendor/bin/php-cs-fixer fix --dry-run
+ *
+ * To run a full check, with automated fixing of each problem :
+ *
+ * ./component/backend/vendor/bin/php-cs-fixer fix
+ *
+ * You can run the clean up on a single file if you need to, this is faster
+ *
+ * ./component/backend/vendor/bin/php-cs-fixer fix --dry-run administrator/index.php
+ * ./component/backend/vendor/bin/php-cs-fixer fix administrator/index.php
+ */
+
+// Add all the core Joomla folders
+$finder = PhpCsFixer\Finder::create()
+ ->in(
+ [
+ __DIR__ . '/src',
+ ]
+ )
+ // Ignore template files as PHP CS fixer can't handle them properly
+ // https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues/3702#issuecomment-396717120
+ ->notPath('/vendor/')
+ ->notPath('/tmpl/');
+
+$config = new PhpCsFixer\Config();
+$config
+ ->setRiskyAllowed(true)
+ ->setHideProgress(false)
+ ->setUsingCache(false)
+ ->setRules(
+ [
+ // Basic ruleset is PSR 12
+ '@PSR12' => true,
+ // Short array syntax
+ 'array_syntax' => ['syntax' => 'short'],
+ // Lists should not have a trailing comma like list($foo, $bar,) = ...
+ 'no_trailing_comma_in_list_call' => true,
+ // Arrays on multiline should have a trailing comma
+ 'trailing_comma_in_multiline' => ['elements' => ['arrays']],
+ // Align elements in multiline array and variable declarations on new lines below each other
+ 'binary_operator_spaces' => ['operators' => ['=>' => 'align_single_space_minimal', '=' => 'align']],
+ // The "No break" comment in switch statements
+ 'no_break_comment' => ['comment_text' => 'No break'],
+ ]
+ )
+ ->setFinder($finder);
+
+return $config;
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index bd378b6..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,49 +0,0 @@
-sudo: true
-language: php
-services:
- - xvfb
-
-env:
- global:
- - RUN_PHPCS="no"
-
-matrix:
- fast_finish: true
- include:
- - php: 7.2
- sudo: true
- env: RUN_PHPCS="yes"
- - php: 7.3
-
-before_script:
-# Forcing localhost in hosts file
-- sudo sed -i '1s/^/127.0.0.1 localhost\n/' /etc/hosts
-- sudo apt-get update -qq
-- sudo apt-get install -y --force-yes apache2 libapache2-mod-fastcgi > /dev/null
-- sudo mkdir $(pwd)/.run
-- chmod a+x tests/travis-php-fpm.sh
-- sudo ./tests/travis-php-fpm.sh $USER $(phpenv version-name)
-- sudo a2enmod rewrite actions fastcgi alias
-- echo "cgi.fix_pathinfo = 1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini
-- ~/.phpenv/versions/$(phpenv version-name)/sbin/php-fpm
-- sudo cp -f tests/travis-ci-apache.conf /etc/apache2/sites-available/default
-- sudo sed -e "s?%TRAVIS_BUILD_DIR%?$(pwd)?g" --in-place /etc/apache2/sites-available/default
-- sudo sed -e "s?%PHPVERSION%?${TRAVIS_PHP_VERSION:0:1}?g" --in-place /etc/apache2/sites-available/default
-- git submodule update --init --recursive
-- sudo service apache2 restart
-# Fluxbox
-- sudo apt-get install fluxbox -y --force-yes
-- fluxbox &
-- sleep 3 # give fluxbox some time to start
-# Composer
-- composer install
-
-script:
-# Build
-- mv jorobo.dist.ini jorobo.ini
-- vendor/bin/robo build
-# System tests (Codeception)
-- mv tests/acceptance.suite.dist.yml tests/acceptance.suite.yml
-- vendor/bin/robo run:tests --use-htaccess
-# Run phpcs on flagged php versions against weblinks source
-- if [[ $RUN_PHPCS == "yes" ]]; then vendor/bin/phpcs --report=full --extensions=php -p --standard=tests/joomla/build/phpcs/Joomla ./src; fi
diff --git a/composer.json b/composer.json
index 702877e..95fc26b 100644
--- a/composer.json
+++ b/composer.json
@@ -19,6 +19,8 @@
"joomla-projects/jorobo": "dev-develop",
"joomla-projects/selenium-server-standalone": "^3.14",
"phpunit/phpunit": "^5.7.27",
+ "friendsofphp/php-cs-fixer": "^3.4.0",
+ "squizlabs/php_codesniffer": "^3.7.1",
"codeception/module-filesystem": "^1.0",
"codeception/module-asserts": "^1.3",
"phpstan/phpstan": "^1.10",
diff --git a/composer.lock b/composer.lock
index 7ff310d..7358279 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "a5269e8ba3b32ffc908f41e3301bb68c",
+ "content-hash": "5d1d209f067fc75fbbc014518681134a",
"packages": [],
"packages-dev": [
{
@@ -546,30 +546,30 @@
},
{
"name": "composer/pcre",
- "version": "2.1.0",
+ "version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/composer/pcre.git",
- "reference": "3fdb2807b31a78a40ad89570e30ec77466c98717"
+ "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/pcre/zipball/3fdb2807b31a78a40ad89570e30ec77466c98717",
- "reference": "3fdb2807b31a78a40ad89570e30ec77466c98717",
+ "url": "https://api.github.com/repos/composer/pcre/zipball/67a32d7d6f9f560b726ab25a061b38ff3a80c560",
+ "reference": "67a32d7d6f9f560b726ab25a061b38ff3a80c560",
"shasum": ""
},
"require": {
- "php": "^7.2 || ^8.0"
+ "php": "^5.3.2 || ^7.0 || ^8.0"
},
"require-dev": {
"phpstan/phpstan": "^1.3",
"phpstan/phpstan-strict-rules": "^1.1",
- "symfony/phpunit-bridge": "^5"
+ "symfony/phpunit-bridge": "^4.2 || ^5"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-main": "2.x-dev"
+ "dev-main": "1.x-dev"
}
},
"autoload": {
@@ -597,7 +597,7 @@
],
"support": {
"issues": "https://github.com/composer/pcre/issues",
- "source": "https://github.com/composer/pcre/tree/2.1.0"
+ "source": "https://github.com/composer/pcre/tree/1.0.1"
},
"funding": [
{
@@ -613,7 +613,7 @@
"type": "tidelift"
}
],
- "time": "2022-11-16T18:32:04+00:00"
+ "time": "2022-01-21T20:24:37+00:00"
},
{
"name": "composer/semver",
@@ -698,27 +698,27 @@
},
{
"name": "composer/xdebug-handler",
- "version": "3.0.3",
+ "version": "2.0.5",
"source": {
"type": "git",
"url": "https://github.com/composer/xdebug-handler.git",
- "reference": "ced299686f41dce890debac69273b47ffe98a40c"
+ "reference": "9e36aeed4616366d2b690bdce11f71e9178c579a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c",
- "reference": "ced299686f41dce890debac69273b47ffe98a40c",
+ "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/9e36aeed4616366d2b690bdce11f71e9178c579a",
+ "reference": "9e36aeed4616366d2b690bdce11f71e9178c579a",
"shasum": ""
},
"require": {
- "composer/pcre": "^1 || ^2 || ^3",
- "php": "^7.2.5 || ^8.0",
+ "composer/pcre": "^1",
+ "php": "^5.3.2 || ^7.0 || ^8.0",
"psr/log": "^1 || ^2 || ^3"
},
"require-dev": {
"phpstan/phpstan": "^1.0",
"phpstan/phpstan-strict-rules": "^1.1",
- "symfony/phpunit-bridge": "^6.0"
+ "symfony/phpunit-bridge": "^4.2 || ^5.0 || ^6.0"
},
"type": "library",
"autoload": {
@@ -744,7 +744,7 @@
"support": {
"irc": "irc://irc.freenode.org/composer",
"issues": "https://github.com/composer/xdebug-handler/issues",
- "source": "https://github.com/composer/xdebug-handler/tree/3.0.3"
+ "source": "https://github.com/composer/xdebug-handler/tree/2.0.5"
},
"funding": [
{
@@ -760,7 +760,7 @@
"type": "tidelift"
}
],
- "time": "2022-02-25T21:32:43+00:00"
+ "time": "2022-02-24T20:20:32+00:00"
},
{
"name": "consolidation/annotated-command",
@@ -1213,6 +1213,125 @@
},
"time": "2022-10-27T11:44:00+00:00"
},
+ {
+ "name": "doctrine/annotations",
+ "version": "1.14.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/annotations.git",
+ "reference": "fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/annotations/zipball/fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af",
+ "reference": "fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/lexer": "^1 || ^2",
+ "ext-tokenizer": "*",
+ "php": "^7.1 || ^8.0",
+ "psr/cache": "^1 || ^2 || ^3"
+ },
+ "require-dev": {
+ "doctrine/cache": "^1.11 || ^2.0",
+ "doctrine/coding-standard": "^9 || ^10",
+ "phpstan/phpstan": "~1.4.10 || ^1.8.0",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "symfony/cache": "^4.4 || ^5.4 || ^6",
+ "vimeo/psalm": "^4.10"
+ },
+ "suggest": {
+ "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Benjamin Eberlei",
+ "email": "kontakt@beberlei.de"
+ },
+ {
+ "name": "Jonathan Wage",
+ "email": "jonwage@gmail.com"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
+ }
+ ],
+ "description": "Docblock Annotations Parser",
+ "homepage": "https://www.doctrine-project.org/projects/annotations.html",
+ "keywords": [
+ "annotations",
+ "docblock",
+ "parser"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/annotations/issues",
+ "source": "https://github.com/doctrine/annotations/tree/1.14.3"
+ },
+ "time": "2023-02-01T09:20:38+00:00"
+ },
+ {
+ "name": "doctrine/deprecations",
+ "version": "v1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/deprecations.git",
+ "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de",
+ "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1|^8.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^9",
+ "phpunit/phpunit": "^7.5|^8.5|^9.5",
+ "psr/log": "^1|^2|^3"
+ },
+ "suggest": {
+ "psr/log": "Allows logging deprecations via PSR-3 logger implementation"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
+ "homepage": "https://www.doctrine-project.org/",
+ "support": {
+ "issues": "https://github.com/doctrine/deprecations/issues",
+ "source": "https://github.com/doctrine/deprecations/tree/v1.0.0"
+ },
+ "time": "2022-05-02T15:47:09+00:00"
+ },
{
"name": "doctrine/instantiator",
"version": "1.5.0",
@@ -1283,6 +1402,84 @@
],
"time": "2022-12-30T00:15:36+00:00"
},
+ {
+ "name": "doctrine/lexer",
+ "version": "2.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/lexer.git",
+ "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/lexer/zipball/39ab8fcf5a51ce4b85ca97c7a7d033eb12831124",
+ "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/deprecations": "^1.0",
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^9 || ^10",
+ "phpstan/phpstan": "^1.3",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "psalm/plugin-phpunit": "^0.18.3",
+ "vimeo/psalm": "^4.11 || ^5.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Common\\Lexer\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
+ }
+ ],
+ "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
+ "homepage": "https://www.doctrine-project.org/projects/lexer.html",
+ "keywords": [
+ "annotations",
+ "docblock",
+ "lexer",
+ "parser",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/lexer/issues",
+ "source": "https://github.com/doctrine/lexer/tree/2.1.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-12-14T08:49:07+00:00"
+ },
{
"name": "felixfbecker/advanced-json-rpc",
"version": "v3.2.1",
@@ -1328,6 +1525,95 @@
},
"time": "2021-06-11T22:34:44+00:00"
},
+ {
+ "name": "friendsofphp/php-cs-fixer",
+ "version": "v3.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
+ "reference": "47177af1cfb9dab5d1cc4daf91b7179c2efe7fad"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/47177af1cfb9dab5d1cc4daf91b7179c2efe7fad",
+ "reference": "47177af1cfb9dab5d1cc4daf91b7179c2efe7fad",
+ "shasum": ""
+ },
+ "require": {
+ "composer/semver": "^3.2",
+ "composer/xdebug-handler": "^2.0",
+ "doctrine/annotations": "^1.12",
+ "ext-json": "*",
+ "ext-tokenizer": "*",
+ "php": "^7.2.5 || ^8.0",
+ "php-cs-fixer/diff": "^2.0",
+ "symfony/console": "^4.4.20 || ^5.1.3 || ^6.0",
+ "symfony/event-dispatcher": "^4.4.20 || ^5.0 || ^6.0",
+ "symfony/filesystem": "^4.4.20 || ^5.0 || ^6.0",
+ "symfony/finder": "^4.4.20 || ^5.0 || ^6.0",
+ "symfony/options-resolver": "^4.4.20 || ^5.0 || ^6.0",
+ "symfony/polyfill-mbstring": "^1.23",
+ "symfony/polyfill-php80": "^1.23",
+ "symfony/polyfill-php81": "^1.23",
+ "symfony/process": "^4.4.20 || ^5.0 || ^6.0",
+ "symfony/stopwatch": "^4.4.20 || ^5.0 || ^6.0"
+ },
+ "require-dev": {
+ "justinrainbow/json-schema": "^5.2",
+ "keradus/cli-executor": "^1.5",
+ "mikey179/vfsstream": "^1.6.8",
+ "php-coveralls/php-coveralls": "^2.5.2",
+ "php-cs-fixer/accessible-object": "^1.1",
+ "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2",
+ "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1",
+ "phpspec/prophecy": "^1.15",
+ "phpspec/prophecy-phpunit": "^1.1 || ^2.0",
+ "phpunit/phpunit": "^8.5.21 || ^9.5",
+ "phpunitgoodpractices/polyfill": "^1.5",
+ "phpunitgoodpractices/traits": "^1.9.1",
+ "symfony/phpunit-bridge": "^5.2.4 || ^6.0",
+ "symfony/yaml": "^4.4.20 || ^5.0 || ^6.0"
+ },
+ "suggest": {
+ "ext-dom": "For handling output formats in XML",
+ "ext-mbstring": "For handling non-UTF8 characters."
+ },
+ "bin": [
+ "php-cs-fixer"
+ ],
+ "type": "application",
+ "autoload": {
+ "psr-4": {
+ "PhpCsFixer\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Dariusz RumiĆski",
+ "email": "dariusz.ruminski@gmail.com"
+ }
+ ],
+ "description": "A tool to automatically fix PHP code style",
+ "support": {
+ "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues",
+ "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.4.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/keradus",
+ "type": "github"
+ }
+ ],
+ "time": "2021-12-11T16:25:08+00:00"
+ },
{
"name": "fzaninotto/faker",
"version": "v1.9.2",
@@ -2660,6 +2946,59 @@
},
"time": "2023-03-03T17:20:24+00:00"
},
+ {
+ "name": "php-cs-fixer/diff",
+ "version": "v2.0.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHP-CS-Fixer/diff.git",
+ "reference": "29dc0d507e838c4580d018bd8b5cb412474f7ec3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/29dc0d507e838c4580d018bd8b5cb412474f7ec3",
+ "reference": "29dc0d507e838c4580d018bd8b5cb412474f7ec3",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.6 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^5.7.23 || ^6.4.3 || ^7.0",
+ "symfony/process": "^3.3"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
+ }
+ ],
+ "description": "sebastian/diff v3 backport support for PHP 5.6+",
+ "homepage": "https://github.com/PHP-CS-Fixer",
+ "keywords": [
+ "diff"
+ ],
+ "support": {
+ "issues": "https://github.com/PHP-CS-Fixer/diff/issues",
+ "source": "https://github.com/PHP-CS-Fixer/diff/tree/v2.0.2"
+ },
+ "abandoned": true,
+ "time": "2020-10-14T08:32:19+00:00"
+ },
{
"name": "php-webdriver/webdriver",
"version": "1.13.1",
@@ -3485,6 +3824,55 @@
"abandoned": true,
"time": "2017-06-30T09:13:00+00:00"
},
+ {
+ "name": "psr/cache",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/cache.git",
+ "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8",
+ "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Cache\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for caching libraries",
+ "keywords": [
+ "cache",
+ "psr",
+ "psr-6"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/cache/tree/master"
+ },
+ "time": "2016-08-06T20:24:11+00:00"
+ },
{
"name": "psr/container",
"version": "2.0.1",
@@ -4467,6 +4855,63 @@
},
"time": "2016-10-03T07:35:21+00:00"
},
+ {
+ "name": "squizlabs/php_codesniffer",
+ "version": "3.7.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
+ "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ed8e00df0a83aa96acf703f8c2979ff33341f879",
+ "reference": "ed8e00df0a83aa96acf703f8c2979ff33341f879",
+ "shasum": ""
+ },
+ "require": {
+ "ext-simplexml": "*",
+ "ext-tokenizer": "*",
+ "ext-xmlwriter": "*",
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0"
+ },
+ "bin": [
+ "bin/phpcs",
+ "bin/phpcbf"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.x-dev"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Greg Sherwood",
+ "role": "lead"
+ }
+ ],
+ "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.",
+ "homepage": "https://github.com/squizlabs/PHP_CodeSniffer",
+ "keywords": [
+ "phpcs",
+ "standards",
+ "static analysis"
+ ],
+ "support": {
+ "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues",
+ "source": "https://github.com/squizlabs/PHP_CodeSniffer",
+ "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki"
+ },
+ "time": "2023-02-22T23:07:41+00:00"
+ },
{
"name": "symfony/console",
"version": "v5.4.23",
@@ -4990,6 +5435,75 @@
],
"time": "2023-02-16T09:33:00+00:00"
},
+ {
+ "name": "symfony/options-resolver",
+ "version": "v5.4.21",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/options-resolver.git",
+ "reference": "4fe5cf6ede71096839f0e4b4444d65dd3a7c1eb9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/options-resolver/zipball/4fe5cf6ede71096839f0e4b4444d65dd3a7c1eb9",
+ "reference": "4fe5cf6ede71096839f0e4b4444d65dd3a7c1eb9",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/deprecation-contracts": "^2.1|^3",
+ "symfony/polyfill-php73": "~1.0",
+ "symfony/polyfill-php80": "^1.16"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\OptionsResolver\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides an improved replacement for the array_replace PHP function",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "config",
+ "configuration",
+ "options"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/options-resolver/tree/v5.4.21"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-02-14T08:03:56+00:00"
+ },
{
"name": "symfony/polyfill-ctype",
"version": "v1.27.0",
@@ -5482,6 +5996,85 @@
],
"time": "2022-11-03T14:55:06+00:00"
},
+ {
+ "name": "symfony/polyfill-php81",
+ "version": "v1.27.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php81.git",
+ "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a",
+ "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.27-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Php81\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php81/tree/v1.27.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-11-03T14:55:06+00:00"
+ },
{
"name": "symfony/process",
"version": "v5.4.23",
@@ -5605,6 +6198,68 @@
},
"time": "2019-05-28T07:50:59+00:00"
},
+ {
+ "name": "symfony/stopwatch",
+ "version": "v5.4.21",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/stopwatch.git",
+ "reference": "f83692cd869a6f2391691d40a01e8acb89e76fee"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/f83692cd869a6f2391691d40a01e8acb89e76fee",
+ "reference": "f83692cd869a6f2391691d40a01e8acb89e76fee",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=7.2.5",
+ "symfony/service-contracts": "^1|^2|^3"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Stopwatch\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides a way to profile code",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/stopwatch/tree/v5.4.21"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2023-02-14T08:03:56+00:00"
+ },
{
"name": "symfony/string",
"version": "v5.4.22",
diff --git a/cypress.config.dist.js b/cypress.config.dist.js
new file mode 100644
index 0000000..1cdb906
--- /dev/null
+++ b/cypress.config.dist.js
@@ -0,0 +1,36 @@
+const { defineConfig } = require('cypress')
+
+module.exports = defineConfig({
+ fixturesFolder: 'tests/cypress/fixtures',
+ videosFolder: 'tests/cypress/output/videos',
+ screenshotsFolder: 'tests/cypress/output/screenshots',
+ viewportHeight: 1000,
+ viewportWidth: 1200,
+ e2e: {
+ setupNodeEvents(on, config) {},
+ baseUrl: 'http://localhost/',
+ specPattern: [
+ 'tests/cypress/integration/install/*.cy.{js,jsx,ts,tsx}',
+ 'tests/cypress/integration/administrator/**/*.cy.{js,jsx,ts,tsx}',
+ 'tests/cypress/integration/site/**/*.cy.{js,jsx,ts,tsx}'
+ ],
+ supportFile: 'tests/cypress/support/index.js',
+ scrollBehavior: 'center',
+ browser: 'firefox',
+ screenshotOnRunFailure: true,
+ video: false
+ },
+ env: {
+ sitename: 'Joomla CMS Test',
+ name: 'jane doe',
+ email: 'admin@example.com',
+ username: 'ci-admin',
+ password: 'joomla-17082005',
+ db_type: 'MySQLi',
+ db_host: 'localhost',
+ db_name: 'test_joomla',
+ db_user: 'root',
+ db_password: 'joomla_ut',
+ db_prefix: 'jos_',
+ },
+})
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..4de0d6e
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,1942 @@
+{
+ "name": "joomla-weblinks",
+ "version": "4.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "joomla-weblinks",
+ "version": "4.0.0",
+ "license": "GPL-2.0-or-later",
+ "devDependencies": {
+ "cypress": "^12.7.0",
+ "joomla-cypress": "^0.0.16"
+ },
+ "engines": {
+ "node": ">=16",
+ "npm": ">=8.5.5"
+ }
+ },
+ "node_modules/@colors/colors": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
+ "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.1.90"
+ }
+ },
+ "node_modules/@cypress/request": {
+ "version": "2.88.11",
+ "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.11.tgz",
+ "integrity": "sha512-M83/wfQ1EkspjkE2lNWNV5ui2Cv7UCv1swW1DqljahbzLVWltcsexQh8jYtuS/vzFXP+HySntGM83ZXA9fn17w==",
+ "dev": true,
+ "dependencies": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "http-signature": "~1.3.6",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "performance-now": "^2.1.0",
+ "qs": "~6.10.3",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.5.0",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^8.3.2"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/@cypress/xvfb": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz",
+ "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^3.1.0",
+ "lodash.once": "^4.1.1"
+ }
+ },
+ "node_modules/@cypress/xvfb/node_modules/debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/@types/node": {
+ "version": "14.18.47",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.47.tgz",
+ "integrity": "sha512-OuJi8bIng4wYHHA3YpKauL58dZrPxro3d0tabPHyiNF8rKfGKuVfr83oFlPLmKri1cX+Z3cJP39GXmnqkP11Gw==",
+ "dev": true
+ },
+ "node_modules/@types/sinonjs__fake-timers": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.1.tgz",
+ "integrity": "sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==",
+ "dev": true
+ },
+ "node_modules/@types/sizzle": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz",
+ "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==",
+ "dev": true
+ },
+ "node_modules/@types/yauzl": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/aggregate-error": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+ "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+ "dev": true,
+ "dependencies": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-colors": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",
+ "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^0.21.3"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/arch": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz",
+ "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/asn1": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
+ "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
+ "dev": true,
+ "dependencies": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "node_modules/assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/astral-regex": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+ "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/async": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
+ "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==",
+ "dev": true
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "dev": true
+ },
+ "node_modules/at-least-node": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
+ "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==",
+ "dev": true,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/aws4": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz",
+ "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==",
+ "dev": true
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
+ "dev": true,
+ "dependencies": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
+ "node_modules/blob-util": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz",
+ "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==",
+ "dev": true
+ },
+ "node_modules/bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+ "dev": true
+ },
+ "node_modules/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,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "node_modules/buffer-crc32": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
+ "dev": true,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/cachedir": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz",
+ "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==",
+ "dev": true
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/chalk/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/check-more-types": {
+ "version": "2.24.0",
+ "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz",
+ "integrity": "sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/ci-info": {
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz",
+ "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/clean-stack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/cli-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+ "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+ "dev": true,
+ "dependencies": {
+ "restore-cursor": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cli-table3": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz",
+ "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.2.0"
+ },
+ "engines": {
+ "node": "10.* || >= 12.*"
+ },
+ "optionalDependencies": {
+ "@colors/colors": "1.5.0"
+ }
+ },
+ "node_modules/cli-truncate": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
+ "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
+ "dev": true,
+ "dependencies": {
+ "slice-ansi": "^3.0.0",
+ "string-width": "^4.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/colorette": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+ "dev": true
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/commander": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
+ "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/common-tags": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.2.tgz",
+ "integrity": "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
+ "dev": true
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/cypress": {
+ "version": "12.12.0",
+ "resolved": "https://registry.npmjs.org/cypress/-/cypress-12.12.0.tgz",
+ "integrity": "sha512-UU5wFQ7SMVCR/hyKok/KmzG6fpZgBHHfrXcHzDmPHWrT+UUetxFzQgt7cxCszlwfozckzwkd22dxMwl/vNkWRw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "dependencies": {
+ "@cypress/request": "^2.88.10",
+ "@cypress/xvfb": "^1.2.4",
+ "@types/node": "^14.14.31",
+ "@types/sinonjs__fake-timers": "8.1.1",
+ "@types/sizzle": "^2.3.2",
+ "arch": "^2.2.0",
+ "blob-util": "^2.0.2",
+ "bluebird": "^3.7.2",
+ "buffer": "^5.6.0",
+ "cachedir": "^2.3.0",
+ "chalk": "^4.1.0",
+ "check-more-types": "^2.24.0",
+ "cli-cursor": "^3.1.0",
+ "cli-table3": "~0.6.1",
+ "commander": "^6.2.1",
+ "common-tags": "^1.8.0",
+ "dayjs": "^1.10.4",
+ "debug": "^4.3.4",
+ "enquirer": "^2.3.6",
+ "eventemitter2": "6.4.7",
+ "execa": "4.1.0",
+ "executable": "^4.1.1",
+ "extract-zip": "2.0.1",
+ "figures": "^3.2.0",
+ "fs-extra": "^9.1.0",
+ "getos": "^3.2.1",
+ "is-ci": "^3.0.0",
+ "is-installed-globally": "~0.4.0",
+ "lazy-ass": "^1.6.0",
+ "listr2": "^3.8.3",
+ "lodash": "^4.17.21",
+ "log-symbols": "^4.0.0",
+ "minimist": "^1.2.8",
+ "ospath": "^1.2.2",
+ "pretty-bytes": "^5.6.0",
+ "proxy-from-env": "1.0.0",
+ "request-progress": "^3.0.0",
+ "semver": "^7.3.2",
+ "supports-color": "^8.1.1",
+ "tmp": "~0.2.1",
+ "untildify": "^4.0.0",
+ "yauzl": "^2.10.0"
+ },
+ "bin": {
+ "cypress": "bin/cypress"
+ },
+ "engines": {
+ "node": "^14.0.0 || ^16.0.0 || >=18.0.0"
+ }
+ },
+ "node_modules/dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
+ "dev": true,
+ "dependencies": {
+ "assert-plus": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/dayjs": {
+ "version": "1.11.7",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz",
+ "integrity": "sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==",
+ "dev": true
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
+ "dev": true,
+ "dependencies": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "node_modules/end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/enquirer": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
+ "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-colors": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/eventemitter2": {
+ "version": "6.4.7",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz",
+ "integrity": "sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==",
+ "dev": true
+ },
+ "node_modules/execa": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
+ "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.0",
+ "get-stream": "^5.0.0",
+ "human-signals": "^1.1.1",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.0",
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2",
+ "strip-final-newline": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/executable": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz",
+ "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==",
+ "dev": true,
+ "dependencies": {
+ "pify": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "dev": true
+ },
+ "node_modules/extract-zip": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
+ "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.1.1",
+ "get-stream": "^5.1.0",
+ "yauzl": "^2.10.0"
+ },
+ "bin": {
+ "extract-zip": "cli.js"
+ },
+ "engines": {
+ "node": ">= 10.17.0"
+ },
+ "optionalDependencies": {
+ "@types/yauzl": "^2.9.1"
+ }
+ },
+ "node_modules/extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==",
+ "dev": true,
+ "engines": [
+ "node >=0.6.0"
+ ]
+ },
+ "node_modules/fd-slicer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+ "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
+ "dev": true,
+ "dependencies": {
+ "pend": "~1.2.0"
+ }
+ },
+ "node_modules/figures": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
+ "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
+ "dev": true,
+ "dependencies": {
+ "escape-string-regexp": "^1.0.5"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==",
+ "dev": true,
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/form-data": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+ "dev": true,
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 0.12"
+ }
+ },
+ "node_modules/fs-extra": {
+ "version": "9.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
+ "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
+ "dev": true,
+ "dependencies": {
+ "at-least-node": "^1.0.0",
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
+ "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-proto": "^1.0.1",
+ "has-symbols": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/getos": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz",
+ "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==",
+ "dev": true,
+ "dependencies": {
+ "async": "^3.2.0"
+ }
+ },
+ "node_modules/getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
+ "dev": true,
+ "dependencies": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/global-dirs": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz",
+ "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==",
+ "dev": true,
+ "dependencies": {
+ "ini": "2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
+ "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/http-signature": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz",
+ "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==",
+ "dev": true,
+ "dependencies": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^2.0.2",
+ "sshpk": "^1.14.1"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/human-signals": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
+ "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.12.0"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "node_modules/ini": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz",
+ "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/is-ci": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz",
+ "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==",
+ "dev": true,
+ "dependencies": {
+ "ci-info": "^3.2.0"
+ },
+ "bin": {
+ "is-ci": "bin.js"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-installed-globally": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz",
+ "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==",
+ "dev": true,
+ "dependencies": {
+ "global-dirs": "^3.0.0",
+ "is-path-inside": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
+ "dev": true
+ },
+ "node_modules/is-unicode-supported": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
+ "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "node_modules/isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==",
+ "dev": true
+ },
+ "node_modules/joomla-cypress": {
+ "version": "0.0.16",
+ "resolved": "https://registry.npmjs.org/joomla-cypress/-/joomla-cypress-0.0.16.tgz",
+ "integrity": "sha512-Ku+ykwChSklRmmIhRMeGmVk4vLCUG2TWAAUseFMo8Yg0cD1jB9csK4pTiwwOBhx7TvT3Sps/RFk68eh3y/cTJw==",
+ "dev": true
+ },
+ "node_modules/jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==",
+ "dev": true
+ },
+ "node_modules/json-schema": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
+ "dev": true
+ },
+ "node_modules/json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
+ "dev": true
+ },
+ "node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dev": true,
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/jsprim": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz",
+ "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==",
+ "dev": true,
+ "engines": [
+ "node >=0.6.0"
+ ],
+ "dependencies": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.4.0",
+ "verror": "1.10.0"
+ }
+ },
+ "node_modules/lazy-ass": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz",
+ "integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==",
+ "dev": true,
+ "engines": {
+ "node": "> 0.8"
+ }
+ },
+ "node_modules/listr2": {
+ "version": "3.14.0",
+ "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz",
+ "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==",
+ "dev": true,
+ "dependencies": {
+ "cli-truncate": "^2.1.0",
+ "colorette": "^2.0.16",
+ "log-update": "^4.0.0",
+ "p-map": "^4.0.0",
+ "rfdc": "^1.3.0",
+ "rxjs": "^7.5.1",
+ "through": "^2.3.8",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "enquirer": ">= 2.3.0 < 3"
+ },
+ "peerDependenciesMeta": {
+ "enquirer": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true
+ },
+ "node_modules/lodash.once": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+ "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
+ "dev": true
+ },
+ "node_modules/log-symbols": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
+ "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.1.0",
+ "is-unicode-supported": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz",
+ "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==",
+ "dev": true,
+ "dependencies": {
+ "ansi-escapes": "^4.3.0",
+ "cli-cursor": "^3.1.0",
+ "slice-ansi": "^4.0.0",
+ "wrap-ansi": "^6.2.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/slice-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
+ "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "astral-regex": "^2.0.0",
+ "is-fullwidth-code-point": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/log-update/node_modules/wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.12.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
+ "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ospath": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz",
+ "integrity": "sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==",
+ "dev": true
+ },
+ "node_modules/p-map": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+ "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+ "dev": true,
+ "dependencies": {
+ "aggregate-error": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
+ "dev": true
+ },
+ "node_modules/performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==",
+ "dev": true
+ },
+ "node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pretty-bytes": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
+ "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz",
+ "integrity": "sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==",
+ "dev": true
+ },
+ "node_modules/psl": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
+ "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==",
+ "dev": true
+ },
+ "node_modules/pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
+ "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.10.4",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.4.tgz",
+ "integrity": "sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==",
+ "dev": true,
+ "dependencies": {
+ "side-channel": "^1.0.4"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/request-progress": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz",
+ "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==",
+ "dev": true,
+ "dependencies": {
+ "throttleit": "^1.0.0"
+ }
+ },
+ "node_modules/restore-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+ "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+ "dev": true,
+ "dependencies": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/rfdc": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz",
+ "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==",
+ "dev": true
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/rxjs": {
+ "version": "7.8.1",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
+ "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
+ "dev": true,
+ "dependencies": {
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true
+ },
+ "node_modules/semver": {
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
+ "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.0",
+ "get-intrinsic": "^1.0.2",
+ "object-inspect": "^1.9.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true
+ },
+ "node_modules/slice-ansi": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
+ "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "astral-regex": "^2.0.0",
+ "is-fullwidth-code-point": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/sshpk": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
+ "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
+ "dev": true,
+ "dependencies": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ },
+ "bin": {
+ "sshpk-conv": "bin/sshpk-conv",
+ "sshpk-sign": "bin/sshpk-sign",
+ "sshpk-verify": "bin/sshpk-verify"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/throttleit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz",
+ "integrity": "sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==",
+ "dev": true
+ },
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
+ "dev": true
+ },
+ "node_modules/tmp": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
+ "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
+ "dev": true,
+ "dependencies": {
+ "rimraf": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8.17.0"
+ }
+ },
+ "node_modules/tough-cookie": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+ "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+ "dev": true,
+ "dependencies": {
+ "psl": "^1.1.28",
+ "punycode": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
+ "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==",
+ "dev": true
+ },
+ "node_modules/tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==",
+ "dev": true
+ },
+ "node_modules/type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/universalify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/untildify": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
+ "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "dev": true,
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
+ "dev": true,
+ "engines": [
+ "node >=0.6.0"
+ ],
+ "dependencies": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "node_modules/yauzl": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
+ "dev": true,
+ "dependencies": {
+ "buffer-crc32": "~0.2.3",
+ "fd-slicer": "~1.1.0"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..72dca7b
--- /dev/null
+++ b/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "joomla-weblinks",
+ "version": "4.0.0",
+ "description": "Weblinks extension",
+ "license": "GPL-2.0-or-later",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/joomla-extensions/weblinks.git"
+ },
+ "engines": {
+ "node": ">=16",
+ "npm": ">=8.5.5"
+ },
+ "scripts": {
+ "cypress:install": "cypress install",
+ "cypress:open": "cypress open",
+ "cypress:run": "cypress run"
+ },
+ "dependencies": {
+ },
+ "devDependencies": {
+ "cypress": "^12.7.0",
+ "joomla-cypress": "^0.0.16"
+ }
+}
diff --git a/phpstan.neon b/phpstan.neon
new file mode 100644
index 0000000..5a27c34
--- /dev/null
+++ b/phpstan.neon
@@ -0,0 +1,11 @@
+includes:
+ - vendor/phpstan/phpstan-deprecation-rules/rules.neon
+parameters:
+ level: 6
+ paths:
+ - src
+ scanDirectories:
+ - joomla/libraries
+ - joomla/administrator/components/com_finder/src/Indexer
+ ignoreErrors:
+ reportUnmatchedIgnoredErrors: false
diff --git a/ruleset.xml b/ruleset.xml
new file mode 100644
index 0000000..7d69c2c
--- /dev/null
+++ b/ruleset.xml
@@ -0,0 +1,48 @@
+
+
+ The Joomla CMS PSR-12 exceptions.
+
+
+
+
+ src/administrator/components/com_weblinks/layouts/*
+
+
+
+
+
+
+
+
+
+
+
+
+ src/administrator/components/com_weblinks/script\.php
+ src/administrator/manifests/packages/weblinks/script\.php
+ src/administrator/components/com_weblinks/helpers/weblinks\.php
+ src/components/com_weblinks/helpers/icon\.php
+ src/components/com_weblinks/helpers/route\.php
+
+
+
+ src/components/com_weblinks/src/Model/CategoriesModel\.php
+ src/components/com_weblinks/src/Model/CategoryModel\.php
+ src/components/com_weblinks/src/Model/WeblinkModel\.php
+ src/administrator/components/com_weblinks/src/Table/*\.php
+
+
+
+ src/administrator/components/com_weblinks/script\.php
+ src/administrator/manifests/packages/weblinks/script\.php
+
+
+
+ src/administrator/components/com_weblinks/src/Table/*\.php
+
+
+
+ src/administrator/components/com_weblinks/script\.php
+ src/administrator/manifests/packages/weblinks/script\.php
+
+
diff --git a/src/administrator/components/com_weblinks/helpers/weblinks.php b/src/administrator/components/com_weblinks/helpers/weblinks.php
index 8e19ede..46baefc 100644
--- a/src/administrator/components/com_weblinks/helpers/weblinks.php
+++ b/src/administrator/components/com_weblinks/helpers/weblinks.php
@@ -1,4 +1,5 @@
load(array('extension' => 'com_weblinks', 'title' => 'Uncategorised')))
- {
- $category->extension = 'com_weblinks';
- $category->title = 'Uncategorised';
- $category->description = '';
- $category->published = 1;
- $category->access = 1;
- $category->params = '{"category_layout":"","image":""}';
- $category->metadata = '{"author":"","robots":""}';
- $category->metadesc = '';
- $category->metakey = '';
- $category->language = '*';
- $category->checked_out_time = null;
- $category->version = 1;
- $category->hits = 0;
- $category->modified_user_id = 0;
- $category->checked_out = null;
+ // Check if the Uncategorised category exists before adding it
+ if (!$category->load(['extension' => 'com_weblinks', 'title' => 'Uncategorised'])) {
+ $category->extension = 'com_weblinks';
+ $category->title = 'Uncategorised';
+ $category->description = '';
+ $category->published = 1;
+ $category->access = 1;
+ $category->params = '{"category_layout":"","image":""}';
+ $category->metadata = '{"author":"","robots":""}';
+ $category->metadesc = '';
+ $category->metakey = '';
+ $category->language = '*';
+ $category->checked_out_time = null;
+ $category->version = 1;
+ $category->hits = 0;
+ $category->modified_user_id = 0;
+ $category->checked_out = null;
- // Set the location in the tree
- $category->setLocation(1, 'last-child');
+ // Set the location in the tree
+ $category->setLocation(1, 'last-child');
- // Check to make sure our data is valid
- if (!$category->check())
- {
- Factory::getApplication()->enqueueMessage(Text::sprintf('COM_WEBLINKS_ERROR_INSTALL_CATEGORY', $category->getError()));
+ // Check to make sure our data is valid
+ if (!$category->check()) {
+ Factory::getApplication()->enqueueMessage(Text::sprintf('COM_WEBLINKS_ERROR_INSTALL_CATEGORY', $category->getError()));
- return;
- }
+ return;
+ }
- // Now store the category
- if (!$category->store(true))
- {
- Factory::getApplication()->enqueueMessage(Text::sprintf('COM_WEBLINKS_ERROR_INSTALL_CATEGORY', $category->getError()));
+ // Now store the category
+ if (!$category->store(true)) {
+ Factory::getApplication()->enqueueMessage(Text::sprintf('COM_WEBLINKS_ERROR_INSTALL_CATEGORY', $category->getError()));
- return;
- }
+ return;
+ }
- // Build the path for our category
- $category->rebuildPath($category->id);
- }
- }
+ // Build the path for our category
+ $category->rebuildPath($category->id);
+ }
+ }
- /**
- * Method to run after the install routine.
- *
- * @param string $type The action being performed
- * @param JInstallerAdapterComponent $parent The class calling this method
- *
- * @return void
- *
- * @since 3.4.1
- */
- public function postflight($type, $parent)
- {
- // Only execute database changes on MySQL databases
- $dbName = Factory::getDbo()->name;
+ /**
+ * Method to run after the install routine.
+ *
+ * @param string $type The action being performed
+ * @param JInstallerAdapterComponent $parent The class calling this method
+ *
+ * @return void
+ *
+ * @since 3.4.1
+ */
+ public function postflight($type, $parent)
+ {
+ // Only execute database changes on MySQL databases
+ $dbName = Factory::getDbo()->name;
- if (strpos($dbName, 'mysql') !== false)
- {
- // Add Missing Table Columns if needed
- $this->addColumnsIfNeeded();
+ if (strpos($dbName, 'mysql') !== false) {
+ // Add Missing Table Columns if needed
+ $this->addColumnsIfNeeded();
- // Drop the Table Columns if needed
- $this->dropColumnsIfNeeded();
- }
+ // Drop the Table Columns if needed
+ $this->dropColumnsIfNeeded();
+ }
- // Insert missing UCM Records if needed
- $this->insertMissingUcmRecords();
- }
+ // Insert missing UCM Records if needed
+ $this->insertMissingUcmRecords();
+ }
- /**
- * Method to insert missing records for the UCM tables
- *
- * @return void
- *
- * @since 3.4.1
- */
- private function insertMissingUcmRecords()
- {
- // Insert the rows in the #__content_types table if they don't exist already
- $db = Factory::getDbo();
+ /**
+ * Method to insert missing records for the UCM tables
+ *
+ * @return void
+ *
+ * @since 3.4.1
+ */
+ private function insertMissingUcmRecords()
+ {
+ // Insert the rows in the #__content_types table if they don't exist already
+ $db = Factory::getDbo();
- // Get the type ID for a Weblink
- $query = $db->getQuery(true);
- $query->select($db->quoteName('type_id'))
- ->from($db->quoteName('#__content_types'))
- ->where($db->quoteName('type_alias') . ' = ' . $db->quote('com_weblinks.weblink'));
- $db->setQuery($query);
+ // Get the type ID for a Weblink
+ $query = $db->getQuery(true);
+ $query->select($db->quoteName('type_id'))
+ ->from($db->quoteName('#__content_types'))
+ ->where($db->quoteName('type_alias') . ' = ' . $db->quote('com_weblinks.weblink'));
+ $db->setQuery($query);
- $weblinkTypeId = $db->loadResult();
+ $weblinkTypeId = $db->loadResult();
- // Get the type ID for a Weblink Category
- $query->clear('where');
- $query->where($db->quoteName('type_alias') . ' = ' . $db->quote('com_weblinks.category'));
- $db->setQuery($query);
+ // Get the type ID for a Weblink Category
+ $query->clear('where');
+ $query->where($db->quoteName('type_alias') . ' = ' . $db->quote('com_weblinks.category'));
+ $db->setQuery($query);
- $categoryTypeId = $db->loadResult();
+ $categoryTypeId = $db->loadResult();
- // Set the table columns to insert table to
- $columnsArray = array(
- $db->quoteName('type_title'),
- $db->quoteName('type_alias'),
- $db->quoteName('table'),
- $db->quoteName('rules'),
- $db->quoteName('field_mappings'),
- $db->quoteName('router'),
- $db->quoteName('content_history_options'),
- );
+ // Set the table columns to insert table to
+ $columnsArray = [
+ $db->quoteName('type_title'),
+ $db->quoteName('type_alias'),
+ $db->quoteName('table'),
+ $db->quoteName('rules'),
+ $db->quoteName('field_mappings'),
+ $db->quoteName('router'),
+ $db->quoteName('content_history_options'),
+ ];
- // If we have no type id for com_weblinks.weblink insert it
- if (!$weblinkTypeId)
- {
- // Insert the data.
- $query->clear();
- $query->insert($db->quoteName('#__content_types'));
- $query->columns($columnsArray);
- $query->values(
- $db->quote('Weblink') . ', '
- . $db->quote('com_weblinks.weblink') . ', '
- . $db->quote(
- '{"special":{"dbtable":"#__weblinks","key":"id","type":"Weblink","prefix":"WeblinksTable","config":"array()"},
+ // If we have no type id for com_weblinks.weblink insert it
+ if (!$weblinkTypeId) {
+ // Insert the data.
+ $query->clear();
+ $query->insert($db->quoteName('#__content_types'));
+ $query->columns($columnsArray);
+ $query->values(
+ $db->quote('Weblink') . ', '
+ . $db->quote('com_weblinks.weblink') . ', '
+ . $db->quote(
+ '{"special":{"dbtable":"#__weblinks","key":"id","type":"Weblink","prefix":"WeblinksTable","config":"array()"},
"common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}'
- ) . ', '
- . $db->quote('') . ', '
- . $db->quote(
- '{"common":{"core_content_item_id":"id","core_title":"title","core_state":"state","core_alias":"alias",
+ ) . ', '
+ . $db->quote('') . ', '
+ . $db->quote(
+ '{"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":"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":"url",
"core_version":"version", "core_ordering":"ordering", "core_metakey":"metakey", "core_metadesc":"metadesc",
"core_catid":"catid", "core_xreference":"xreference", "asset_id":"null"}, "special":{}}'
- ) . ', '
- . $db->quote('WeblinksHelperRoute::getWeblinkRoute') . ', '
- . $db->quote(
- '{"formFile":"administrator\\/components\\/com_weblinks\\/models\\/forms\\/weblink.xml",
+ ) . ', '
+ . $db->quote('WeblinksHelperRoute::getWeblinkRoute') . ', '
+ . $db->quote(
+ '{"formFile":"administrator\\/components\\/com_weblinks\\/models\\/forms\\/weblink.xml",
"hideFields":["asset_id","checked_out","checked_out_time","version","featured","images"], "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"} ]}'
- )
- );
+ )
+ );
- $db->setQuery($query);
- $db->execute();
- }
+ $db->setQuery($query);
+ $db->execute();
+ }
- // If we have no type id for com_weblinks.category insert it
- if (!$categoryTypeId)
- {
- // Insert the data.
- $query->clear();
- $query->insert($db->quoteName('#__content_types'));
- $query->columns($columnsArray);
- $query->values(
- $db->quote('Weblinks Category') . ', '
- . $db->quote('com_weblinks.category') . ', '
- . $db->quote('
+ // If we have no type id for com_weblinks.category insert it
+ if (!$categoryTypeId) {
+ // Insert the data.
+ $query->clear();
+ $query->insert($db->quoteName('#__content_types'));
+ $query->columns($columnsArray);
+ $query->values(
+ $db->quote('Weblinks Category') . ', '
+ . $db->quote('com_weblinks.category') . ', '
+ . $db->quote('
{"special":{"dbtable":"#__categories","key":"id","type":"Category","prefix":"JTable","config":"array()"},
- "common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}'
- ) . ', '
- . $db->quote('') . ', '
- . $db->quote('
+ "common":{"dbtable":"#__ucm_content","key":"ucm_id","type":"Corecontent","prefix":"JTable","config":"array()"}}') . ', '
+ . $db->quote('') . ', '
+ . $db->quote('
{"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"}}'
- ) . ', '
- . $db->quote('WeblinksHelperRoute::getCategoryRoute') . ', '
- . $db->quote('
+ "special":{"parent_id":"parent_id","lft":"lft","rgt":"rgt","level":"level","path":"path","extension":"extension","note":"note"}}') . ', '
+ . $db->quote('WeblinksHelperRoute::getCategoryRoute') . ', '
+ . $db->quote('
{"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",
@@ -277,68 +268,64 @@ class Com_WeblinksInstallerScript
"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"}]}'
- )
- );
+ "displayColumn":"title"}]}')
+ );
- $db->setQuery($query);
- $db->execute();
- }
- }
+ $db->setQuery($query);
+ $db->execute();
+ }
+ }
- /**
- * Method to drop colums from #__weblinks if they still there.
- *
- * @return void
- *
- * @since 3.4.1
- */
- private function dropColumnsIfNeeded()
- {
- $oldColumns = array(
- 'sid',
- 'date',
- 'archived',
- 'approved',
- );
+ /**
+ * Method to drop colums from #__weblinks if they still there.
+ *
+ * @return void
+ *
+ * @since 3.4.1
+ */
+ private function dropColumnsIfNeeded()
+ {
+ $oldColumns = [
+ 'sid',
+ 'date',
+ 'archived',
+ 'approved',
+ ];
- $db = Factory::getDbo();
- $table = $db->getTableColumns('#__weblinks');
+ $db = Factory::getDbo();
+ $table = $db->getTableColumns('#__weblinks');
- $columns = array_intersect($oldColumns, array_keys($table));
+ $columns = array_intersect($oldColumns, array_keys($table));
- foreach ($columns as $column)
- {
- $sql = 'ALTER TABLE ' . $db->quoteName('#__weblinks') . ' DROP COLUMN ' . $db->quoteName($column);
- $db->setQuery($sql);
- $db->execute();
- }
- }
+ foreach ($columns as $column) {
+ $sql = 'ALTER TABLE ' . $db->quoteName('#__weblinks') . ' DROP COLUMN ' . $db->quoteName($column);
+ $db->setQuery($sql);
+ $db->execute();
+ }
+ }
- /**
- * Method to add colums from #__weblinks if they are missing.
- *
- * @return void
- *
- * @since 3.4.1
- */
- private function addColumnsIfNeeded()
- {
- $db = Factory::getDbo();
- $table = $db->getTableColumns('#__weblinks');
+ /**
+ * Method to add colums from #__weblinks if they are missing.
+ *
+ * @return void
+ *
+ * @since 3.4.1
+ */
+ private function addColumnsIfNeeded()
+ {
+ $db = Factory::getDbo();
+ $table = $db->getTableColumns('#__weblinks');
- if (!array_key_exists('version', $table))
- {
- $sql = 'ALTER TABLE ' . $db->quoteName('#__weblinks') . ' ADD COLUMN ' . $db->quoteName('version') . " int unsigned NOT NULL DEFAULT '1'";
- $db->setQuery($sql);
- $db->execute();
- }
+ if (!array_key_exists('version', $table)) {
+ $sql = 'ALTER TABLE ' . $db->quoteName('#__weblinks') . ' ADD COLUMN ' . $db->quoteName('version') . " int unsigned NOT NULL DEFAULT '1'";
+ $db->setQuery($sql);
+ $db->execute();
+ }
- if (!array_key_exists('images', $table))
- {
- $sql = 'ALTER TABLE ' . $db->quoteName('#__weblinks') . ' ADD COLUMN ' . $db->quoteName('images') . ' text NOT NULL';
- $db->setQuery($sql);
- $db->execute();
- }
- }
+ if (!array_key_exists('images', $table)) {
+ $sql = 'ALTER TABLE ' . $db->quoteName('#__weblinks') . ' ADD COLUMN ' . $db->quoteName('images') . ' text NOT NULL';
+ $db->setQuery($sql);
+ $db->execute();
+ }
+ }
}
diff --git a/src/administrator/components/com_weblinks/services/provider.php b/src/administrator/components/com_weblinks/services/provider.php
index a9470bd..b794e32 100644
--- a/src/administrator/components/com_weblinks/services/provider.php
+++ b/src/administrator/components/com_weblinks/services/provider.php
@@ -1,4 +1,5 @@
set(AssociationExtensionInterface::class, new AssociationsHelper);
-
- $componentNamespace = '\\Joomla\\Component\\Weblinks';
-
- $container->registerServiceProvider(new CategoryFactory($componentNamespace));
- $container->registerServiceProvider(new MVCFactory($componentNamespace));
- $container->registerServiceProvider(new ComponentDispatcherFactory($componentNamespace));
- $container->registerServiceProvider(new RouterFactory($componentNamespace));
-
- $container->set(
- ComponentInterface::class,
- function (Container $container) {
- $component = new WeblinksComponent($container->get(ComponentDispatcherFactoryInterface::class));
-
- $component->setRegistry($container->get(Registry::class));
- $component->setMVCFactory($container->get(MVCFactoryInterface::class));
- $component->setCategoryFactory($container->get(CategoryFactoryInterface::class));
- $component->setAssociationExtension($container->get(AssociationExtensionInterface::class));
- $component->setRouterFactory($container->get(RouterFactoryInterface::class));
-
- return $component;
- }
- );
- }
+return new class () implements ServiceProviderInterface {
+ /**
+ * Registers the service provider with a DI container.
+ *
+ * @param Container $container The DI container.
+ *
+ * @return void
+ *
+ * @since 4.0.0
+ */
+ public function register(Container $container)
+ {
+ $container->set(AssociationExtensionInterface::class, new AssociationsHelper());
+ $componentNamespace = '\\Joomla\\Component\\Weblinks';
+ $container->registerServiceProvider(new CategoryFactory($componentNamespace));
+ $container->registerServiceProvider(new MVCFactory($componentNamespace));
+ $container->registerServiceProvider(new ComponentDispatcherFactory($componentNamespace));
+ $container->registerServiceProvider(new RouterFactory($componentNamespace));
+ $container->set(ComponentInterface::class, function (Container $container) {
+ $component = new WeblinksComponent($container->get(ComponentDispatcherFactoryInterface::class));
+ $component->setRegistry($container->get(Registry::class));
+ $component->setMVCFactory($container->get(MVCFactoryInterface::class));
+ $component->setCategoryFactory($container->get(CategoryFactoryInterface::class));
+ $component->setAssociationExtension($container->get(AssociationExtensionInterface::class));
+ $component->setRouterFactory($container->get(RouterFactoryInterface::class));
+ return $component;
+ });
+ }
};
diff --git a/src/administrator/components/com_weblinks/src/Controller/DisplayController.php b/src/administrator/components/com_weblinks/src/Controller/DisplayController.php
index 67fcf1f..813bab9 100644
--- a/src/administrator/components/com_weblinks/src/Controller/DisplayController.php
+++ b/src/administrator/components/com_weblinks/src/Controller/DisplayController.php
@@ -1,4 +1,5 @@
input->get('view', 'weblinks');
+ $layout = $this->input->get('layout', 'default');
+ $id = $this->input->getInt('id');
+ // Check for edit form.
+ if ($view == 'weblink' && $layout == 'edit' && !$this->checkEditId('com_weblinks.edit.weblink', $id)) {
+ // Somehow the person just went to the form - we don't allow that.
+ if (!\count($this->app->getMessageQueue())) {
+ $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error');
+ }
- /**
- * Method to display a view.
- *
- * @param boolean $cacheable 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 BaseController|boolean This object to support chaining.
- *
- * @since 1.5
- */
- public function display($cacheable = false, $urlparams = false)
- {
- $view = $this->input->get('view', 'weblinks');
- $layout = $this->input->get('layout', 'default');
- $id = $this->input->getInt('id');
+ $this->setRedirect(Route::_('index.php?option=com_weblinks&view=weblinks', false));
+ return false;
+ }
- // Check for edit form.
- if ($view == 'weblink' && $layout == 'edit' && !$this->checkEditId('com_weblinks.edit.weblink', $id))
- {
- // Somehow the person just went to the form - we don't allow that.
- if (!\count($this->app->getMessageQueue()))
- {
- $this->setMessage(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 'error');
- }
-
- $this->setRedirect(Route::_('index.php?option=com_weblinks&view=weblinks', false));
-
- return false;
- }
-
- return parent::display();
- }
+ return parent::display();
+ }
}
diff --git a/src/administrator/components/com_weblinks/src/Controller/WeblinkController.php b/src/administrator/components/com_weblinks/src/Controller/WeblinkController.php
index 6227371..8035403 100644
--- a/src/administrator/components/com_weblinks/src/Controller/WeblinkController.php
+++ b/src/administrator/components/com_weblinks/src/Controller/WeblinkController.php
@@ -1,4 +1,5 @@
input->getInt('filter_category_id'), 'int');
+ /**
+ * 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 = [])
+ {
+ $categoryId = ArrayHelper::getValue($data, 'catid', $this->input->getInt('filter_category_id'), 'int');
- if ($categoryId)
- {
- // If the category has been passed in the URL check it.
- return $this->app->getIdentity()->authorise('core.create', $this->option . '.category.' . $categoryId);
- }
+ if ($categoryId) {
+ // If the category has been passed in the URL check it.
+ return $this->app->getIdentity()->authorise('core.create', $this->option . '.category.' . $categoryId);
+ }
- // In the absence of better information, revert to the component permissions.
- return parent::allowAdd($data);
- }
+ // In the absence of better information, revert to the component permissions.
+ return parent::allowAdd($data);
+ }
- /**
- * Method to check if you can add a new 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;
+ /**
+ * Method to check if you can add a new 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 = [], $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);
- }
+ // 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);
+ // Get the item.
+ $item = $this->getModel()->getItem($recordId);
- // Since there is no item, return false.
- if (empty($item))
- {
- return false;
- }
+ // Since there is no item, return false.
+ if (empty($item)) {
+ return false;
+ }
- $user = $this->app->getIdentity();
+ $user = $this->app->getIdentity();
- // 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 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);
- }
+ // 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 1.7
- */
- public function batch($model = null)
- {
- $this->checkToken();
+ /**
+ * Method to run batch operations.
+ *
+ * @param object $model The model.
+ *
+ * @return boolean True if successful, false otherwise and internal error is set.
+ *
+ * @since 1.7
+ */
+ public function batch($model = null)
+ {
+ $this->checkToken();
- // Set the model
- $model = $this->getModel('Weblink', 'Administrator', array());
+ // Set the model
+ $model = $this->getModel('Weblink', 'Administrator', []);
- // Preset the redirect
- $this->setRedirect(Route::_('index.php?option=com_weblinks&view=weblinks' . $this->getRedirectToListAppend(), false));
+ // Preset the redirect
+ $this->setRedirect(Route::_('index.php?option=com_weblinks&view=weblinks' . $this->getRedirectToListAppend(), false));
- return parent::batch($model);
- }
+ return parent::batch($model);
+ }
- /**
- * 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 1.6
- */
- protected function postSaveHook(BaseDatabaseModel $model, $validData = [])
- {
- $task = $this->getTask();
+ /**
+ * 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 1.6
+ */
+ protected function postSaveHook(BaseDatabaseModel $model, $validData = [])
+ {
+ $task = $this->getTask();
- if ($task == 'save')
- {
- $this->setRedirect(Route::_('index.php?option=com_weblinks&view=weblinks', false));
- }
- }
+ if ($task == 'save') {
+ $this->setRedirect(Route::_('index.php?option=com_weblinks&view=weblinks', false));
+ }
+ }
}
diff --git a/src/administrator/components/com_weblinks/src/Controller/WeblinksController.php b/src/administrator/components/com_weblinks/src/Controller/WeblinksController.php
index 9508b7a..f325805 100644
--- a/src/administrator/components/com_weblinks/src/Controller/WeblinksController.php
+++ b/src/administrator/components/com_weblinks/src/Controller/WeblinksController.php
@@ -1,4 +1,5 @@
true))
- {
- return parent::getModel($name, $prefix, $config);
- }
+ /**
+ * 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 object The model.
+ *
+ * @since 1.6
+ */
+ public function getModel($name = 'Weblink', $prefix = 'Administrator', $config = ['ignore_request' => true])
+ {
+ return parent::getModel($name, $prefix, $config);
+ }
}
diff --git a/src/administrator/components/com_weblinks/src/Extension/WeblinksComponent.php b/src/administrator/components/com_weblinks/src/Extension/WeblinksComponent.php
index 937cba4..877847f 100644
--- a/src/administrator/components/com_weblinks/src/Extension/WeblinksComponent.php
+++ b/src/administrator/components/com_weblinks/src/Extension/WeblinksComponent.php
@@ -1,4 +1,5 @@
getRegistry()->register('weblinksadministrator', new AdministratorService);
- $this->getRegistry()->register('weblinkicon', new Icon($container->get(SiteApplication::class)));
- }
-
- /**
- * Returns a valid section for the given section. If it is not valid then null
- * is returned.
- *
- * @param string $section The section to get the mapping for
- * @param object $item The item
- *
- * @return string|null The new section
- *
- * @since 4.0.0
- */
- public function validateSection($section, $item = null)
- {
- if ($section != 'weblink')
- {
- // We don't know other sections
- return null;
- }
-
- return $section;
- }
-
- /**
- * Returns valid contexts
- *
- * @return array
- *
- * @since 4.0.0
- */
- public function getContexts(): array
- {
- Factory::getLanguage()->load('com_weblinks', JPATH_ADMINISTRATOR);
-
- $contexts = array(
- 'com_weblinks.weblink' => Text::_('COM_WEBLINKS'),
- );
-
- return $contexts;
- }
+ /**
+ * Booting the extension. This is the function to set up the environment of the extension like
+ * registering new class loaders, etc.
+ *
+ * If required, some initial set up can be done from services of the container, eg.
+ * registering HTML services.
+ *
+ * @param ContainerInterface $container The container
+ *
+ * @return void
+ *
+ * @since 4.0.0
+ */
- /**
- * 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 ($section === 'category' ? 'categories' : 'weblinks');
- }
+ public function boot(ContainerInterface $container)
+ {
+ $this->getRegistry()->register('weblinksadministrator', new AdministratorService());
+ $this->getRegistry()->register('weblinkicon', new Icon($container->get(SiteApplication::class)));
+ }
- /**
- * 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 'state';
- }
+ /**
+ * Returns a valid section for the given section. If it is not valid then null
+ * is returned.
+ *
+ * @param string $section The section to get the mapping for
+ * @param object $item The item
+ *
+ * @return string|null The new section
+ *
+ * @since 4.0.0
+ */
+ public function validateSection($section, $item = null)
+ {
+ if ($section != 'weblink') {
+ // We don't know other sections
+ return null;
+ }
+
+ return $section;
+ }
+
+ /**
+ * Returns valid contexts
+ *
+ * @return array
+ *
+ * @since 4.0.0
+ */
+ public function getContexts(): array
+ {
+ Factory::getLanguage()->load('com_weblinks', JPATH_ADMINISTRATOR);
+ $contexts = [
+ 'com_weblinks.weblink' => Text::_('COM_WEBLINKS'),
+ ];
+ return $contexts;
+ }
+
+
+ /**
+ * 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 ($section === 'category' ? 'categories' : 'weblinks');
+ }
+
+ /**
+ * 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 'state';
+ }
}
diff --git a/src/administrator/components/com_weblinks/src/Field/Modal/WeblinkField.php b/src/administrator/components/com_weblinks/src/Field/Modal/WeblinkField.php
index 07bf11b..f4ad905 100644
--- a/src/administrator/components/com_weblinks/src/Field/Modal/WeblinkField.php
+++ b/src/administrator/components/com_weblinks/src/Field/Modal/WeblinkField.php
@@ -1,4 +1,5 @@
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_weblinks', JPATH_ADMINISTRATOR);
+ // The active weblink id field.
+ $value = (int) $this->value > 0 ? (int) $this->value : '';
+ // Create the modal id.
+ $modalId = 'Weblink_' . $this->id;
+ /** @var \Joomla\CMS\WebAsset\WebAssetManager $wa */
+ $wa = Factory::getApplication()->getDocument()->getWebAssetManager();
+ // Add the modal field script to the document head.
+ $wa->useScript('field.modal-fields');
+ // Script to proxy the select modal function to the modal-fields.js file.
+ if ($allowSelect) {
+ static $scriptSelect = null;
+ if (is_null($scriptSelect)) {
+ $scriptSelect = [];
+ }
- /**
- * Method to get the field input markup.
- *
- * @return string The field input markup.
- *
- * @since __DEPLOY_VERSION__
- */
- protected function getInput()
- {
- $allowNew = ((string) $this->element['new'] == 'true');
- $allowEdit = ((string) $this->element['edit'] == 'true');
- $allowClear = ((string) $this->element['clear'] != 'false');
- $allowSelect = ((string) $this->element['select'] != 'false');
-
- // Load language
- Factory::getLanguage()->load('com_weblinks', JPATH_ADMINISTRATOR);
-
- // The active weblink id field.
- $value = (int) $this->value > 0 ? (int) $this->value : '';
-
- // Create the modal id.
- $modalId = 'Weblink_' . $this->id;
-
- /** @var \Joomla\CMS\WebAsset\WebAssetManager $wa */
- $wa = Factory::getApplication()->getDocument()->getWebAssetManager();
-
- // Add the modal field script to the document head.
- $wa->useScript('field.modal-fields');
-
- // 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]))
- {
- $wa->addInlineScript("
+ if (!isset($scriptSelect[$this->id])) {
+ $wa->addInlineScript(
+ "
window.jSelectWeblink_" . $this->id . " = function (id, title, catid, object, url, language) {
window.processModalSelect('Article', '" . $this->id . "', id, title, catid, object, url, language);
}",
- [],
- ['type' => 'module']
- );
+ [],
+ ['type' => 'module']
+ );
+ Text::script('JGLOBAL_ASSOCIATIONS_PROPAGATE_FAILED');
+ $scriptSelect[$this->id] = true;
+ }
+ }
- Text::script('JGLOBAL_ASSOCIATIONS_PROPAGATE_FAILED');
+ // Setup variables for display.
+ $linkWeblinks = 'index.php?option=com_weblinks&view=weblinks&layout=modal&tmpl=component&' . Session::getFormToken() . '=1';
+ $linkWeblink = 'index.php?option=com_weblinks&view=weblink&layout=modal&tmpl=component&' . Session::getFormToken() . '=1';
+ $modalTitle = Text::_('COM_WEBLINKS_CHANGE_WEBLINK');
+ if (isset($this->element['language'])) {
+ $linkWeblinks .= '&forcedLanguage=' . $this->element['language'];
+ $linkWeblink .= '&forcedLanguage=' . $this->element['language'];
+ $modalTitle .= ' — ' . $this->element['label'];
+ }
- $scriptSelect[$this->id] = true;
- }
- }
+ $urlSelect = $linkWeblinks . '&function=jSelectWeblink_' . $this->id;
+ $urlEdit = $linkWeblink . '&task=weblink.edit&id=\' + document.getElementById("' . $this->id . '_id").value + \'';
+ $urlNew = $linkWeblink . '&task=weblink.add';
+ if ($value) {
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true)
+ ->select($db->quoteName('title'))
+ ->from($db->quoteName('#__weblinks'))
+ ->where($db->quoteName('id') . ' = :id')
+ ->bind(':id', $value, ParameterType::INTEGER);
+ $db->setQuery($query);
+ try {
+ $title = $db->loadResult();
+ } catch (\RuntimeException $e) {
+ Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
+ }
+ }
- // Setup variables for display.
- $linkWeblinks = 'index.php?option=com_weblinks&view=weblinks&layout=modal&tmpl=component&' . Session::getFormToken() . '=1';
- $linkWeblink = 'index.php?option=com_weblinks&view=weblink&layout=modal&tmpl=component&' . Session::getFormToken() . '=1';
- $modalTitle = Text::_('COM_WEBLINKS_CHANGE_WEBLINK');
+ $title = empty($title) ? Text::_('COM_WEBLINKS_SELECT_A_WEBLINK') : htmlspecialchars($title, ENT_QUOTES, 'UTF-8');
+ // The current weblink display field.
+ $html = '';
+ if ($allowSelect || $allowNew || $allowEdit || $allowClear) {
+ $html .= '';
+ }
- if (isset($this->element['language']))
- {
- $linkWeblinks .= '&forcedLanguage=' . $this->element['language'];
- $linkWeblink .= '&forcedLanguage=' . $this->element['language'];
- $modalTitle .= ' — ' . $this->element['label'];
- }
+ $html .= ' ';
+ // Select weblink button
+ if ($allowSelect) {
+ $html .= ''
+ . ' ' . Text::_('JSELECT')
+ . ' ';
+ }
- $urlSelect = $linkWeblinks . '&function=jSelectWeblink_' . $this->id;
- $urlEdit = $linkWeblink . '&task=weblink.edit&id=\' + document.getElementById("' . $this->id . '_id").value + \'';
- $urlNew = $linkWeblink . '&task=weblink.add';
+ // New weblink button
+ if ($allowNew) {
+ $html .= ''
+ . ' ' . Text::_('JACTION_CREATE')
+ . ' ';
+ }
- if ($value)
- {
- $db = Factory::getDbo();
- $query = $db->getQuery(true)
- ->select($db->quoteName('title'))
- ->from($db->quoteName('#__weblinks'))
- ->where($db->quoteName('id') . ' = :id')
- ->bind(':id', $value, ParameterType::INTEGER);
- $db->setQuery($query);
+ // Edit weblink button
+ if ($allowEdit) {
+ $html .= ''
+ . ' ' . Text::_('JACTION_EDIT')
+ . ' ';
+ }
- try
- {
- $title = $db->loadResult();
- }
- catch (\RuntimeException $e)
- {
- Factory::getApplication()->enqueueMessage($e->getMessage(), 'error');
- }
- }
+ // Clear weblink button
+ if ($allowClear) {
+ $html .= ''
+ . ' ' . Text::_('JCLEAR')
+ . ' ';
+ }
- $title = empty($title) ? Text::_('COM_WEBLINKS_SELECT_A_WEBLINK') : htmlspecialchars($title, ENT_QUOTES, 'UTF-8');
+ if ($allowSelect || $allowNew || $allowEdit || $allowClear) {
+ $html .= ' ';
+ }
- // The current weblink display field.
- $html = '';
+ // Select weblink modal
+ if ($allowSelect) {
+ $html .= HTMLHelper::_('bootstrap.renderModal', 'ModalSelect' . $modalId, [
+ 'title' => $modalTitle,
+ 'url' => $urlSelect,
+ 'height' => '400px',
+ 'width' => '800px',
+ 'bodyHeight' => 70,
+ 'modalWidth' => 80,
+ 'footer' => ''
+ . Text::_('JLIB_HTML_BEHAVIOR_CLOSE') . ' ',
+ ]);
+ }
- if ($allowSelect || $allowNew || $allowEdit || $allowClear)
- {
- $html .= '';
- }
+ $closeButtonClick = "window.processModalEdit(this, '$this->id', 'add', 'weblink', 'cancel', 'weblink-form'); return false;";
+ $saveButtonClick = "window.processModalEdit(this, '$this->id', 'add', 'weblink', 'save', 'weblink-form'); return false;";
+ $applyButtonClick = "window.processModalEdit(this, '$this->id', 'add', 'weblink', 'apply', 'weblink-form'); return false;";
+ // New weblink modal
+ if ($allowNew) {
+ $html .= HTMLHelper::_('bootstrap.renderModal', 'ModalNew' . $modalId, [
+ 'title' => Text::_('COM_WEBLINKS_NEW_WEBLINK'),
+ 'backdrop' => 'static',
+ 'keyboard' => false,
+ 'closeButton' => false,
+ 'url' => $urlNew,
+ 'height' => '400px',
+ 'width' => '800px',
+ 'bodyHeight' => '70',
+ 'modalWidth' => '80',
+ 'footer' => ''
+ . Text::_('JLIB_HTML_BEHAVIOR_CLOSE') . ' '
+ . ''
+ . Text::_('JSAVE') . ' '
+ . ''
+ . Text::_('JAPPLY') . ' ',
+ ]);
+ }
- $html .= ' ';
+ // Edit weblink modal
+ if ($allowEdit) {
+ $html .= HTMLHelper::_('bootstrap.renderModal', 'ModalEdit' . $modalId, [
+ 'title' => Text::_('COM_WEBLINKS_EDIT_WEBLINK'),
+ 'backdrop' => 'static',
+ 'keyboard' => false,
+ 'closeButton' => false,
+ 'url' => $urlEdit,
+ 'height' => '400px',
+ 'width' => '800px',
+ 'bodyHeight' => '70',
+ 'modalWidth' => '80',
+ 'footer' => ''
+ . Text::_('JLIB_HTML_BEHAVIOR_CLOSE') . ' '
+ . ''
+ . Text::_('JSAVE') . ' '
+ . ''
+ . Text::_('JAPPLY') . ' ',
+ ]);
+ }
- // Select weblink button
- if ($allowSelect)
- {
- $html .= ''
- . ' ' . Text::_('JSELECT')
- . ' ';
- }
+ // Note: class='required' for client side validation.
+ $class = $this->required ? ' class="required modal-value"' : '';
+ $html .= ' ';
+ return $html;
+ }
- // New weblink button
- if ($allowNew)
- {
- $html .= ''
- . ' ' . Text::_('JACTION_CREATE')
- . ' ';
- }
-
- // Edit weblink button
- if ($allowEdit)
- {
- $html .= ''
- . ' ' . Text::_('JACTION_EDIT')
- . ' ';
- }
-
- // Clear weblink button
- if ($allowClear)
- {
- $html .= ''
- . ' ' . Text::_('JCLEAR')
- . ' ';
- }
-
- if ($allowSelect || $allowNew || $allowEdit || $allowClear)
- {
- $html .= ' ';
- }
-
- // Select weblink modal
- if ($allowSelect)
- {
- $html .= HTMLHelper::_(
- 'bootstrap.renderModal',
- 'ModalSelect' . $modalId,
- array(
- 'title' => $modalTitle,
- 'url' => $urlSelect,
- 'height' => '400px',
- 'width' => '800px',
- 'bodyHeight' => 70,
- 'modalWidth' => 80,
- 'footer' => ''
- . Text::_('JLIB_HTML_BEHAVIOR_CLOSE') . ' ',
- )
- );
- }
-
- $closeButtonClick = "window.processModalEdit(this, '$this->id', 'add', 'weblink', 'cancel', 'weblink-form'); return false;";
- $saveButtonClick = "window.processModalEdit(this, '$this->id', 'add', 'weblink', 'save', 'weblink-form'); return false;";
- $applyButtonClick = "window.processModalEdit(this, '$this->id', 'add', 'weblink', 'apply', 'weblink-form'); return false;";
-
- // New weblink modal
- if ($allowNew)
- {
- $html .= HTMLHelper::_(
- 'bootstrap.renderModal',
- 'ModalNew' . $modalId,
- array(
- 'title' => Text::_('COM_WEBLINKS_NEW_WEBLINK'),
- 'backdrop' => 'static',
- 'keyboard' => false,
- 'closeButton' => false,
- 'url' => $urlNew,
- 'height' => '400px',
- 'width' => '800px',
- 'bodyHeight' => '70',
- 'modalWidth' => '80',
- 'footer' => ''
- . Text::_('JLIB_HTML_BEHAVIOR_CLOSE') . ' '
- . ''
- . Text::_('JSAVE') . ' '
- . ''
- . Text::_('JAPPLY') . ' ',
- )
- );
- }
-
- // Edit weblink modal
- if ($allowEdit)
- {
- $html .= HTMLHelper::_(
- 'bootstrap.renderModal',
- 'ModalEdit' . $modalId,
- array(
- 'title' => Text::_('COM_WEBLINKS_EDIT_WEBLINK'),
- 'backdrop' => 'static',
- 'keyboard' => false,
- 'closeButton' => false,
- 'url' => $urlEdit,
- 'height' => '400px',
- 'width' => '800px',
- 'bodyHeight' => '70',
- 'modalWidth' => '80',
- 'footer' => ''
- . Text::_('JLIB_HTML_BEHAVIOR_CLOSE') . ' '
- . ''
- . Text::_('JSAVE') . ' '
- . ''
- . Text::_('JAPPLY') . ' ',
- )
- );
- }
-
- // 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 __DEPLOY_VERSION__
- */
- protected function getLabel()
- {
- return str_replace($this->id, $this->id . '_name', parent::getLabel());
- }
+ /**
+ * Method to get the field label markup.
+ *
+ * @return string The field label markup.
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ protected function getLabel()
+ {
+ return str_replace($this->id, $this->id . '_name', parent::getLabel());
+ }
}
diff --git a/src/administrator/components/com_weblinks/src/Helper/AssociationsHelper.php b/src/administrator/components/com_weblinks/src/Helper/AssociationsHelper.php
index 45d4129..5ee4d89 100644
--- a/src/administrator/components/com_weblinks/src/Helper/AssociationsHelper.php
+++ b/src/administrator/components/com_weblinks/src/Helper/AssociationsHelper.php
@@ -1,4 +1,5 @@
getType($typeName);
+ /**
+ * Get the associated items for an item
+ *
+ * @param string $typeName The item type
+ * @param int $id The id of item for which we need the associated items
+ *
+ * @return array
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function getAssociations($typeName, $id)
+ {
+ $type = $this->getType($typeName);
+ $context = $this->extension . '.item';
+ $catidField = 'catid';
+ if ($typeName === 'category') {
+ $context = 'com_categories.item';
+ $catidField = '';
+ }
- $context = $this->extension . '.item';
- $catidField = 'catid';
+ // Get the associations.
+ $associations = Associations::getAssociations($this->extension, $type['tables']['a'], $context, $id, 'id', 'alias', $catidField);
+ return $associations;
+ }
- if ($typeName === 'category')
- {
- $context = 'com_categories.item';
- $catidField = '';
- }
+ /**
+ * Get item information
+ *
+ * @param string $typeName The item type
+ * @param int $id The id of item for which we need the associated items
+ *
+ * @return Table|null
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function getItem($typeName, $id)
+ {
+ if (empty($id)) {
+ return null;
+ }
- // Get the associations.
- $associations = Associations::getAssociations(
- $this->extension,
- $type['tables']['a'],
- $context,
- $id,
- 'id',
- 'alias',
- $catidField
- );
+ $table = null;
+ switch ($typeName) {
+ case 'weblink':
+ $table = Table::getInstance('WeblinkTable', 'Joomla\\Component\\Weblinks\\Administrator\\Table\\');
- return $associations;
- }
+ break;
+ case 'category':
+ $table = Table::getInstance('Category', 'Joomla\\CMS\\Table\\');
- /**
- * Get item information
- *
- * @param string $typeName The item type
- * @param int $id The id of item for which we need the associated items
- *
- * @return Table|null
- *
- * @since __DEPLOY_VERSION__
- */
- public function getItem($typeName, $id)
- {
- if (empty($id))
- {
- return null;
- }
+ break;
+ }
- $table = null;
+ if (empty($table)) {
+ return null;
+ }
- switch ($typeName)
- {
- case 'weblink':
- $table = Table::getInstance('WeblinkTable', 'Joomla\\Component\\Weblinks\\Administrator\\Table\\');
- break;
+ $table->load($id);
+ return $table;
+ }
- case 'category':
- $table = Table::getInstance('Category', 'Joomla\\CMS\\Table\\');
- break;
- }
+ /**
+ * Get information about the type
+ *
+ * @param string $typeName The item type
+ *
+ * @return array Array of item types
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function getType($typeName = '')
+ {
+ $fields = $this->getFieldsTemplate();
+ $tables = [];
+ $joins = [];
+ $support = $this->getSupportTemplate();
+ $title = '';
+ if (in_array($typeName, $this->itemTypes)) {
+ switch ($typeName) {
+ case 'weblink':
+ $support['state'] = true;
+ $support['acl'] = true;
+ $support['checkout'] = true;
+ $support['category'] = true;
+ $support['save2copy'] = true;
+ $tables = [
+ 'a' => '#__weblinks',
+ ];
+ $title = 'weblink';
- if (empty($table))
- {
- return null;
- }
+ 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 = [
+ 'a' => '#__categories',
+ ];
+ $title = 'category';
- $table->load($id);
+ break;
+ }
+ }
- return $table;
- }
-
- /**
- * Get information about the type
- *
- * @param string $typeName The item type
- *
- * @return array Array of item types
- *
- * @since __DEPLOY_VERSION__
- */
- public function getType($typeName = '')
- {
- $fields = $this->getFieldsTemplate();
- $tables = array();
- $joins = array();
- $support = $this->getSupportTemplate();
- $title = '';
-
- if (in_array($typeName, $this->itemTypes))
- {
- switch ($typeName)
- {
- case 'weblink':
-
- $support['state'] = true;
- $support['acl'] = true;
- $support['checkout'] = true;
- $support['category'] = true;
- $support['save2copy'] = true;
-
- $tables = array(
- 'a' => '#__weblinks',
- );
-
- $title = 'weblink';
- 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,
- );
- }
+ return [
+ 'fields' => $fields,
+ 'support' => $support,
+ 'tables' => $tables,
+ 'joins' => $joins,
+ 'title' => $title,
+ ];
+ }
}
diff --git a/src/administrator/components/com_weblinks/src/Helper/WeblinksHelper.php b/src/administrator/components/com_weblinks/src/Helper/WeblinksHelper.php
index 823b8c7..816b207 100644
--- a/src/administrator/components/com_weblinks/src/Helper/WeblinksHelper.php
+++ b/src/administrator/components/com_weblinks/src/Helper/WeblinksHelper.php
@@ -1,4 +1,5 @@
id) || $record->state != -2)
- {
- return false;
- }
+ /**
+ * 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 1.6
+ */
+ protected function canDelete($record)
+ {
+ if (empty($record->id) || $record->state != -2) {
+ return false;
+ }
- return $this->getCurrentUser()->authorise('core.delete', 'com_weblinks.category.' . (int) $record->catid);
- }
+ return $this->getCurrentUser()->authorise('core.delete', 'com_weblinks.category.' . (int) $record->catid);
+ }
- /**
- * Method to test whether a record can be deleted.
- *
- * @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 1.6
- */
- protected function canEditState($record)
- {
- if (!empty($record->catid))
- {
- return $this->getCurrentUser()->authorise('core.edit.state', 'com_weblinks.category.' . (int) $record->catid);
- }
+ /**
+ * Method to test whether a record can be deleted.
+ *
+ * @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 1.6
+ */
+ protected function canEditState($record)
+ {
+ if (!empty($record->catid)) {
+ return $this->getCurrentUser()->authorise('core.edit.state', 'com_weblinks.category.' . (int) $record->catid);
+ }
- return parent::canEditState($record);
- }
+ return parent::canEditState($record);
+ }
- /**
- * 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 1.6
- */
- public function getForm($data = array(), $loadData = true)
- {
- // Get the form.
- $form = $this->loadForm('com_weblinks.weblink', 'weblink', array('control' => 'jform', 'load_data' => $loadData));
+ /**
+ * 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 1.6
+ */
+ public function getForm($data = [], $loadData = true)
+ {
+ // Get the form.
+ $form = $this->loadForm('com_weblinks.weblink', 'weblink', ['control' => 'jform', 'load_data' => $loadData]);
- if (empty($form))
- {
- return false;
- }
+ if (empty($form)) {
+ return false;
+ }
- // Determine correct permissions to check.
- if ($this->getState('weblink.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');
- }
+ // Determine correct permissions to check.
+ if ($this->getState('weblink.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('state', 'disabled', 'true');
- $form->setFieldAttribute('publish_up', 'disabled', 'true');
- $form->setFieldAttribute('publish_down', 'disabled', 'true');
+ // Modify the form based on access controls.
+ if (!$this->canEditState((object) $data)) {
+ // Disable fields for display.
+ $form->setFieldAttribute('ordering', 'disabled', 'true');
+ $form->setFieldAttribute('state', 'disabled', 'true');
+ $form->setFieldAttribute('publish_up', 'disabled', 'true');
+ $form->setFieldAttribute('publish_down', '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');
- $form->setFieldAttribute('publish_up', 'filter', 'unset');
- $form->setFieldAttribute('publish_down', 'filter', 'unset');
- }
+ // 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');
+ $form->setFieldAttribute('publish_up', 'filter', 'unset');
+ $form->setFieldAttribute('publish_down', 'filter', 'unset');
+ }
- // Don't allow to change the created_by user if not allowed to access com_users.
- if (!$this->getCurrentUser()->authorise('core.manage', 'com_users'))
- {
- $form->setFieldAttribute('created_by', 'filter', 'unset');
- }
+ // Don't allow to change the created_by user if not allowed to access com_users.
+ if (!$this->getCurrentUser()->authorise('core.manage', 'com_users')) {
+ $form->setFieldAttribute('created_by', 'filter', 'unset');
+ }
- return $form;
- }
+ return $form;
+ }
- /**
- * Method to get the data that should be injected in the form.
- *
- * @return array The default data is an empty array.
- *
- * @since 1.6
- */
- protected function loadFormData()
- {
- $app = Factory::getApplication();
+ /**
+ * Method to get the data that should be injected in the form.
+ *
+ * @return array The default data is an empty array.
+ *
+ * @since 1.6
+ */
+ protected function loadFormData()
+ {
+ $app = Factory::getApplication();
- // Check the session for previously entered form data.
- $data = $app->getUserState('com_weblinks.edit.weblink.data', array());
+ // Check the session for previously entered form data.
+ $data = $app->getUserState('com_weblinks.edit.weblink.data', []);
- if (empty($data))
- {
- $data = $this->getItem();
+ if (empty($data)) {
+ $data = $this->getItem();
- // Prime some default values.
- if ($this->getState('weblink.id') == 0)
- {
- $data->set('catid', $app->input->get('catid', $app->getUserState('com_weblinks.weblinks.filter.category_id'), 'int'));
- }
- }
+ // Prime some default values.
+ if ($this->getState('weblink.id') == 0) {
+ $data->set('catid', $app->input->get('catid', $app->getUserState('com_weblinks.weblinks.filter.category_id'), 'int'));
+ }
+ }
- $this->preprocessData('com_weblinks.weblink', $data);
+ $this->preprocessData('com_weblinks.weblink', $data);
- return $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)
- {
- if ($item = parent::getItem($pk))
- {
- // Convert the metadata field to an array.
- $registry = new Registry($item->metadata ?? '');
- $item->metadata = $registry->toArray();
+ /**
+ * 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();
- // Convert the images field to an array.
- $registry = new Registry($item->images ?? '');
- $item->images = $registry->toArray();
+ // Convert the images field to an array.
+ $registry = new Registry($item->images ?? '');
+ $item->images = $registry->toArray();
- // Load associated web links items
- $assoc = Associations::isEnabled();
+ // Load associated web links items
+ $assoc = Associations::isEnabled();
- if ($assoc)
- {
- $item->associations = array();
+ if ($assoc) {
+ $item->associations = [];
- if ($item->id != null)
- {
- $associations = Associations::getAssociations('com_weblinks', '#__weblinks', 'com_weblinks.item', $item->id);
+ if ($item->id != null) {
+ $associations = Associations::getAssociations('com_weblinks', '#__weblinks', 'com_weblinks.item', $item->id);
- foreach ($associations as $tag => $association)
- {
- $item->associations[$tag] = $association->id;
- }
- }
- }
+ foreach ($associations as $tag => $association) {
+ $item->associations[$tag] = $association->id;
+ }
+ }
+ }
- if (!empty($item->id))
- {
- $item->tags = new TagsHelper;
- $item->tags->getTagIds($item->id, 'com_weblinks.weblink');
- $item->metadata['tags'] = $item->tags;
- }
- }
+ if (!empty($item->id)) {
+ $item->tags = new TagsHelper();
+ $item->tags->getTagIds($item->id, 'com_weblinks.weblink');
+ $item->metadata['tags'] = $item->tags;
+ }
+ }
- return $item;
- }
+ return $item;
+ }
- /**
- * Prepare and sanitise the table data prior to saving.
- *
- * @param \Joomla\CMS\Table\Table $table A reference to a JTable object.
- *
- * @return void
- *
- * @since 1.6
- */
- protected function prepareTable($table)
- {
- $date = Factory::getDate();
- $user = $this->getCurrentUser();
+ /**
+ * Prepare and sanitise the table data prior to saving.
+ *
+ * @param \Joomla\CMS\Table\Table $table A reference to a JTable object.
+ *
+ * @return void
+ *
+ * @since 1.6
+ */
+ protected function prepareTable($table)
+ {
+ $date = Factory::getDate();
+ $user = $this->getCurrentUser();
- $table->title = htmlspecialchars_decode($table->title, ENT_QUOTES);
- $table->alias = ApplicationHelper::stringURLSafe($table->alias);
+ $table->title = htmlspecialchars_decode($table->title, ENT_QUOTES);
+ $table->alias = ApplicationHelper::stringURLSafe($table->alias);
- if (empty($table->alias))
- {
- $table->alias = ApplicationHelper::stringURLSafe($table->title);
- }
+ if (empty($table->alias)) {
+ $table->alias = ApplicationHelper::stringURLSafe($table->title);
+ }
- if (empty($table->id))
- {
- // Set the values
+ if (empty($table->id)) {
+ // Set the values
- // Set ordering to the last item if not set
- if (empty($table->ordering))
- {
- $db = $this->getDatabase();
- $query = $db->getQuery(true)
- ->select('MAX(ordering)')
- ->from($db->quoteName('#__weblinks'));
+ // Set ordering to the last item if not set
+ if (empty($table->ordering)) {
+ $db = $this->getDatabase();
+ $query = $db->getQuery(true)
+ ->select('MAX(ordering)')
+ ->from($db->quoteName('#__weblinks'));
- $db->setQuery($query);
- $max = $db->loadResult();
+ $db->setQuery($query);
+ $max = $db->loadResult();
- $table->ordering = $max + 1;
- }
- else
- {
- // Set the values
- $table->modified = $date->toSql();
- $table->modified_by = $user->id;
- }
- }
+ $table->ordering = $max + 1;
+ } else {
+ // Set the values
+ $table->modified = $date->toSql();
+ $table->modified_by = $user->id;
+ }
+ }
- // Increment the weblink version number.
- $table->version++;
- }
+ // Increment the weblink version number.
+ $table->version++;
+ }
- /**
- * A protected method to get a set of ordering conditions.
- *
- * @param \Joomla\CMS\Table\Table $table A JTable object.
- *
- * @return array An array of conditions to add to ordering queries.
- *
- * @since 1.6
- */
- protected function getReorderConditions($table)
- {
- $condition = array();
- $condition[] = 'catid = ' . (int) $table->catid;
+ /**
+ * A protected method to get a set of ordering conditions.
+ *
+ * @param \Joomla\CMS\Table\Table $table A JTable object.
+ *
+ * @return array An array of conditions to add to ordering queries.
+ *
+ * @since 1.6
+ */
+ protected function getReorderConditions($table)
+ {
+ $condition = [];
+ $condition[] = 'catid = ' . (int) $table->catid;
- return $condition;
- }
+ return $condition;
+ }
- /**
- * Method to save the form data.
- *
- * @param array $data The form data.
- *
- * @return boolean True on success.
- *
- * @since 3.1
- */
- public function save($data)
- {
- $app = Factory::getApplication();
+ /**
+ * Method to save the form data.
+ *
+ * @param array $data The form data.
+ *
+ * @return boolean True on success.
+ *
+ * @since 3.1
+ */
+ public function save($data)
+ {
+ $app = Factory::getApplication();
- // Cast catid to integer for comparison
- $catid = (int) $data['catid'];
+ // Cast catid to integer for comparison
+ $catid = (int) $data['catid'];
- // Check if New Category exists
- if ($catid > 0)
- {
- $catid = CategoriesHelper::validateCategoryId($data['catid'], 'com_weblinks');
- }
+ // Check if New Category exists
+ if ($catid > 0) {
+ $catid = CategoriesHelper::validateCategoryId($data['catid'], 'com_weblinks');
+ }
- // Save New Category
- if ($catid == 0 && $this->canCreateCategory())
- {
- $table = array();
- $table['title'] = $data['catid'];
- $table['parent_id'] = 1;
- $table['extension'] = 'com_weblinks';
- $table['language'] = $data['language'];
- $table['published'] = 1;
+ // Save New Category
+ if ($catid == 0 && $this->canCreateCategory()) {
+ $table = [];
+ $table['title'] = $data['catid'];
+ $table['parent_id'] = 1;
+ $table['extension'] = 'com_weblinks';
+ $table['language'] = $data['language'];
+ $table['published'] = 1;
- // Create new category and get catid back
- $data['catid'] = CategoriesHelper::createCategory($table);
- }
+ // Create new category and get catid back
+ $data['catid'] = CategoriesHelper::createCategory($table);
+ }
- // Alter the title for save as copy
- if ($app->input->get('task') == 'save2copy')
- {
- [$name, $alias] = $this->generateNewTitle($data['catid'], $data['alias'], $data['title']);
- $data['title'] = $name;
- $data['alias'] = $alias;
- $data['state'] = 0;
- }
+ // Alter the title for save as copy
+ if ($app->input->get('task') == 'save2copy') {
+ [$name, $alias] = $this->generateNewTitle($data['catid'], $data['alias'], $data['title']);
+ $data['title'] = $name;
+ $data['alias'] = $alias;
+ $data['state'] = 0;
+ }
- return parent::save($data);
- }
+ return parent::save($data);
+ }
- /**
- * 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();
+ /**
+ * 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->title)
- {
- $name = StringHelper::increment($name);
- }
+ while ($table->load(['alias' => $alias, 'catid' => $category_id])) {
+ if ($name == $table->title) {
+ $name = StringHelper::increment($name);
+ }
- $alias = StringHelper::increment($alias, 'dash');
- }
+ $alias = StringHelper::increment($alias, 'dash');
+ }
- return array($name, $alias);
- }
+ return [$name, $alias];
+ }
- /**
- * 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.0
- */
- protected function preprocessForm(\JForm $form, $data, $group = 'content')
- {
- if ($this->canCreateCategory())
- {
- $form->setFieldAttribute('catid', 'allowAdd', 'true');
- }
+ /**
+ * 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.0
+ */
+ protected function preprocessForm(\JForm $form, $data, $group = 'content')
+ {
+ if ($this->canCreateCategory()) {
+ $form->setFieldAttribute('catid', 'allowAdd', 'true');
+ }
- // Association weblinks items
- if (Associations::isEnabled())
- {
- $languages = LanguageHelper::getContentLanguages(false, false, null, 'ordering', 'asc');
+ // Association weblinks items
+ if (Associations::isEnabled()) {
+ $languages = LanguageHelper::getContentLanguages(false, false, 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');
+ 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_weblink');
- $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');
- $field->addAttribute('addfieldprefix', 'Joomla\\Component\\Weblinks\\Administrator\\Field');
- }
+ foreach ($languages as $language) {
+ $field = $fieldset->addChild('field');
+ $field->addAttribute('name', $language->lang_code);
+ $field->addAttribute('type', 'modal_weblink');
+ $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');
+ $field->addAttribute('addfieldprefix', 'Joomla\\Component\\Weblinks\\Administrator\\Field');
+ }
- $form->load($addform, false);
- }
- }
+ $form->load($addform, false);
+ }
+ }
- parent::preprocessForm($form, $data, $group);
- }
+ parent::preprocessForm($form, $data, $group);
+ }
- /**
- * Is the user allowed to create an on the fly category?
- *
- * @return bool
- *
- * @since 3.6.0
- */
- private function canCreateCategory()
- {
- return $this->getCurrentUser()->authorise('core.create', 'com_weblinks');
- }
+ /**
+ * Is the user allowed to create an on the fly category?
+ *
+ * @return bool
+ *
+ * @since 3.6.0
+ */
+ private function canCreateCategory()
+ {
+ return $this->getCurrentUser()->authorise('core.create', 'com_weblinks');
+ }
}
diff --git a/src/administrator/components/com_weblinks/src/Model/WeblinksModel.php b/src/administrator/components/com_weblinks/src/Model/WeblinksModel.php
index 6a127f6..33339a8 100644
--- a/src/administrator/components/com_weblinks/src/Model/WeblinksModel.php
+++ b/src/administrator/components/com_weblinks/src/Model/WeblinksModel.php
@@ -1,4 +1,5 @@
input->get('forcedLanguage', '', 'cmd');
+ $forcedLanguage = $app->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 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 languages.
+ if ($forcedLanguage) {
+ $this->context .= '.' . $forcedLanguage;
+ }
- // Load the parameters.
- $params = ComponentHelper::getParams('com_weblinks');
- $this->setState('params', $params);
+ // Load the parameters.
+ $params = ComponentHelper::getParams('com_weblinks');
+ $this->setState('params', $params);
- // Force a language.
- if (!empty($forcedLanguage))
- {
- $this->setState('filter.language', $forcedLanguage);
- }
+ // Force a language.
+ if (!empty($forcedLanguage)) {
+ $this->setState('filter.language', $forcedLanguage);
+ }
- // List state information.
- parent::populateState($ordering, $direction);
- }
+ // 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');
- $id .= ':' . $this->getState('filter.category_id');
- $id .= ':' . $this->getState('filter.language');
- $id .= ':' . $this->getState('filter.tag');
- $id .= ':' . $this->getState('filter.level');
+ /**
+ * 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');
+ $id .= ':' . $this->getState('filter.category_id');
+ $id .= ':' . $this->getState('filter.language');
+ $id .= ':' . $this->getState('filter.tag');
+ $id .= ':' . $this->getState('filter.level');
- return parent::getStoreId($id);
- }
+ 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->getDatabase();
- $query = $db->getQuery(true);
- $user = $this->getCurrentUser();
+ /**
+ * Build an SQL query to load the list data.
+ *
+ * @return \JDatabaseQuery
+ *
+ * @since 1.6
+ */
+ protected function getListQuery()
+ {
+ // Create a new query object.
+ $db = $this->getDatabase();
+ $query = $db->getQuery(true);
+ $user = $this->getCurrentUser();
- // 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.created, a.created_by, ' .
- 'a.hits, a.state, a.access, a.ordering, a.language, a.publish_up, a.publish_down'
- )
- );
- $query->from($db->quoteName('#__weblinks', 'a'));
+ // 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.created, a.created_by, ' .
+ 'a.hits, a.state, a.access, a.ordering, a.language, a.publish_up, a.publish_down'
+ )
+ );
+ $query->from($db->quoteName('#__weblinks', 'a'));
- // 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->qn('l.lang_code') . ' = ' . $db->qn('a.language'));
+ // 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->qn('l.lang_code') . ' = ' . $db->qn('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->qn('uc.id') . ' = ' . $db->qn('a.checked_out'));
+ // Join over the users for the checked out user.
+ $query->select($db->quoteName('uc.name', 'editor'))
+ ->join('LEFT', $db->quoteName('#__users', 'uc') . ' ON ' . $db->qn('uc.id') . ' = ' . $db->qn('a.checked_out'));
- // Join over the asset groups.
- $query->select($db->quoteName('ag.title', 'access_level'))
- ->join('LEFT', $db->quoteName('#__viewlevels', 'ag') . ' ON ' . $db->qn('ag.id') . ' = ' . $db->qn('a.access'));
+ // Join over the asset groups.
+ $query->select($db->quoteName('ag.title', 'access_level'))
+ ->join('LEFT', $db->quoteName('#__viewlevels', 'ag') . ' ON ' . $db->qn('ag.id') . ' = ' . $db->qn('a.access'));
- // Join over the categories.
- $query->select('c.title AS category_title')
- ->join('LEFT', $db->quoteName('#__categories', 'c') . ' ON ' . $db->qn('c.id') . ' = ' . $db->qn('a.catid'));
+ // Join over the categories.
+ $query->select('c.title AS category_title')
+ ->join('LEFT', $db->quoteName('#__categories', 'c') . ' ON ' . $db->qn('c.id') . ' = ' . $db->qn('a.catid'));
- // Join over the associations.
- $assoc = Associations::isEnabled();
+ // Join over the associations.
+ $assoc = Associations::isEnabled();
- if ($assoc)
- {
- $query->select('COUNT(asso2.id)>1 AS association')
- ->join('LEFT', $db->quoteName('#__associations', 'asso') . ' ON asso.id = a.id AND asso.context = ' . $db->quote('com_weblinks.item'))
- ->join('LEFT', $db->quoteName('#__associations', 'asso2') . ' ON asso2.key = asso.key')
- ->group('a.id, l.title, l.image, uc.name, ag.title, c.title');
- }
+ if ($assoc) {
+ $query->select('COUNT(asso2.id)>1 AS association')
+ ->join('LEFT', $db->quoteName('#__associations', 'asso') . ' ON asso.id = a.id AND asso.context = ' . $db->quote('com_weblinks.item'))
+ ->join('LEFT', $db->quoteName('#__associations', 'asso2') . ' ON asso2.key = asso.key')
+ ->group('a.id, l.title, l.image, uc.name, ag.title, c.title');
+ }
- // Filter by access level.
- if ($access = $this->getState('filter.access'))
- {
- $query->where($db->quoteName('a.access') . ' = :access')
- ->bind(':access', $access, ParameterType::INTEGER);
- }
+ // Filter by access level.
+ if ($access = $this->getState('filter.access')) {
+ $query->where($db->quoteName('a.access') . ' = :access')
+ ->bind(':access', $access, ParameterType::INTEGER);
+ }
- // Implement View Level Access
- if (!$user->authorise('core.admin'))
- {
- $query->whereIn($db->quoteName('a.access'), $user->getAuthorisedViewLevels());
- }
+ // Implement View Level Access
+ if (!$user->authorise('core.admin')) {
+ $query->whereIn($db->quoteName('a.access'), $user->getAuthorisedViewLevels());
+ }
- // Filter by published state
- $published = (string) $this->getState('filter.published');
+ // Filter by published state
+ $published = (string) $this->getState('filter.published');
- if (is_numeric($published))
- {
- $query->where($db->quoteName('a.state') . ' = :state')
- ->bind(':state', $published, ParameterType::INTEGER);
- }
- elseif ($published === '')
- {
- $query->whereIn($db->quoteName('a.state'), [0, 1]);
- }
+ if (is_numeric($published)) {
+ $query->where($db->quoteName('a.state') . ' = :state')
+ ->bind(':state', $published, ParameterType::INTEGER);
+ } elseif ($published === '') {
+ $query->whereIn($db->quoteName('a.state'), [0, 1]);
+ }
- // Filter by category.
- $categoryId = $this->getState('filter.category_id');
+ // Filter by category.
+ $categoryId = $this->getState('filter.category_id');
- if (is_numeric($categoryId))
- {
- $query->where($db->quoteName('a.catid') . ' = :catid')
- ->bind(':catid', $categoryId, ParameterType::INTEGER);
- }
+ if (is_numeric($categoryId)) {
+ $query->where($db->quoteName('a.catid') . ' = :catid')
+ ->bind(':catid', $categoryId, ParameterType::INTEGER);
+ }
- // Filter on the level.
- if ($level = $this->getState('filter.level'))
- {
- $query->where($db->quoteName('c.level') . ' <= :level')
- ->bind(':level', $level, ParameterType::INTEGER);
- }
+ // Filter on the level.
+ if ($level = $this->getState('filter.level')) {
+ $query->where($db->quoteName('c.level') . ' <= :level')
+ ->bind(':level', $level, ParameterType::INTEGER);
+ }
- // Filter by search in title
- $search = $this->getState('filter.search');
+ // Filter by search in title
+ $search = $this->getState('filter.search');
- if (!empty($search))
- {
- if (stripos($search, 'id:') === 0)
- {
- $search = substr($search, 3);
- $query->where($db->quoteName('a.id') . ' = :id')
- ->bind(':id', $search, ParameterType::INTEGER);
- }
- else
- {
- $search = '%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%');
- $query->where('(' . $db->quoteName('a.title') . ' LIKE :title OR ' . $db->quoteName('a.alias') . ' LIKE :alias)')
- ->bind(':title', $search)
- ->bind(':alias', $search);
- }
- }
+ if (!empty($search)) {
+ if (stripos($search, 'id:') === 0) {
+ $search = substr($search, 3);
+ $query->where($db->quoteName('a.id') . ' = :id')
+ ->bind(':id', $search, ParameterType::INTEGER);
+ } else {
+ $search = '%' . str_replace(' ', '%', $db->escape(trim($search), true) . '%');
+ $query->where('(' . $db->quoteName('a.title') . ' LIKE :title OR ' . $db->quoteName('a.alias') . ' LIKE :alias)')
+ ->bind(':title', $search)
+ ->bind(':alias', $search);
+ }
+ }
- // Filter on the language.
- if ($language = $this->getState('filter.language'))
- {
- $query->where($db->quoteName('a.language') . ' = :language')
- ->bind(':language', $language);
- }
+ // Filter on the language.
+ if ($language = $this->getState('filter.language')) {
+ $query->where($db->quoteName('a.language') . ' = :language')
+ ->bind(':language', $language);
+ }
- $tagId = $this->getState('filter.tag');
+ $tagId = $this->getState('filter.tag');
- // Filter by a single tag.
- if (is_numeric($tagId))
- {
- $query->where($db->quoteName('tagmap.tag_id') . ' = :tagId')
- ->bind(':tagId', $tagId, ParameterType::INTEGER)
- ->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_weblinks.weblink')
- );
- }
+ // Filter by a single tag.
+ if (is_numeric($tagId)) {
+ $query->where($db->quoteName('tagmap.tag_id') . ' = :tagId')
+ ->bind(':tagId', $tagId, ParameterType::INTEGER)
+ ->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_weblinks.weblink')
+ );
+ }
- // Add the list ordering clause.
- $orderCol = $this->state->get('list.ordering', 'a.title');
- $orderDirn = $this->state->get('list.direction', 'ASC');
+ // Add the list ordering clause.
+ $orderCol = $this->state->get('list.ordering', 'a.title');
+ $orderDirn = $this->state->get('list.direction', 'ASC');
- if ($orderCol == 'a.ordering' || $orderCol == 'category_title')
- {
- $orderCol = 'c.title ' . $orderDirn . ', a.ordering';
- }
+ if ($orderCol == 'a.ordering' || $orderCol == 'category_title') {
+ $orderCol = 'c.title ' . $orderDirn . ', a.ordering';
+ }
- $query->order($db->escape($orderCol . ' ' . $orderDirn));
+ $query->order($db->escape($orderCol . ' ' . $orderDirn));
- return $query;
- }
+ return $query;
+ }
}
diff --git a/src/administrator/components/com_weblinks/src/Service/HTML/AdministratorService.php b/src/administrator/components/com_weblinks/src/Service/HTML/AdministratorService.php
index 98c560e..8d0944e 100644
--- a/src/administrator/components/com_weblinks/src/Service/HTML/AdministratorService.php
+++ b/src/administrator/components/com_weblinks/src/Service/HTML/AdministratorService.php
@@ -1,4 +1,5 @@
$associated) {
+ $associations[$tag] = (int) $associated->id;
+ }
- // Get the associations
- if ($associations = Associations::getAssociations('com_weblinks', '#__weblinks', 'com_weblinks.item', $weblinkid))
- {
- foreach ($associations as $tag => $associated)
- {
- $associations[$tag] = (int) $associated->id;
- }
+ // Get the associated contact items
+ $db = Factory::getDbo();
+ $query = $db->getQuery(true)
+ ->select([
+ $db->quoteName('c.id'),
+ $db->quoteName('c.title', 'title'),
+ $db->quoteName('l.sef', 'lang_sef'),
+ $db->quoteName('lang_code'),
+ $db->quoteName('cat.title', 'category_title'),
+ $db->quoteName('l.image'),
+ $db->quoteName('l.title', 'language_title'),
+ ])
+ ->from($db->quoteName('#__weblinks', 'c'))
+ ->join('LEFT', $db->quoteName('#__categories', 'cat'), $db->quoteName('cat.id') . ' = ' . $db->quoteName('c.catid'))
+ ->join('LEFT', $db->quoteName('#__languages', 'l'), $db->quoteName('c.language') . ' = ' . $db->quoteName('l.lang_code'))
+ ->whereIn($db->quoteName('c.id'), array_values($associations))
+ ->where($db->quoteName('c.id') . ' != :id')
+ ->bind(':id', $weblinkid, ParameterType::INTEGER);
+ $db->setQuery($query);
+ try {
+ $items = $db->loadObjectList('id');
+ } catch (\RuntimeException $e) {
+ throw new \Exception($e->getMessage(), 500, $e);
+ }
- // Get the associated contact items
- $db = Factory::getDbo();
- $query = $db->getQuery(true)
- ->select(
- [
- $db->quoteName('c.id'),
- $db->quoteName('c.title', 'title'),
- $db->quoteName('l.sef', 'lang_sef'),
- $db->quoteName('lang_code'),
- $db->quoteName('cat.title', 'category_title'),
- $db->quoteName('l.image'),
- $db->quoteName('l.title', 'language_title'),
- ]
- )
- ->from($db->quoteName('#__weblinks', 'c'))
- ->join('LEFT', $db->quoteName('#__categories', 'cat'), $db->quoteName('cat.id') . ' = ' . $db->quoteName('c.catid'))
- ->join('LEFT', $db->quoteName('#__languages', 'l'), $db->quoteName('c.language') . ' = ' . $db->quoteName('l.lang_code'))
- ->whereIn($db->quoteName('c.id'), array_values($associations))
- ->where($db->quoteName('c.id') . ' != :id')
- ->bind(':id', $weblinkid, ParameterType::INTEGER);
- $db->setQuery($query);
+ if ($items) {
+ $app = Factory::getApplication();
+ $languages = LanguageHelper::getContentLanguages([0, 1]);
+ $content_languages = array_column($languages, 'lang_code');
+ foreach ($items as &$item) {
+ if (in_array($item->lang_code, $content_languages)) {
+ $text = $item->lang_code;
+ $url = Route::_('index.php?option=com_weblinks&task=weblink.edit&id=' . (int) $item->id);
+ $tooltip = '' . htmlspecialchars($item->language_title, ENT_QUOTES, 'UTF-8') . ' '
+ . htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8')
+ . ' ' . Text::sprintf('JCATEGORY_SPRINTF', $item->category_title);
+ $classes = 'badge bg-secondary';
+ $item->link = '' . $text . ' '
+ . '' . $tooltip . '
';
+ } else {
+ // Display warning if Content Language is trashed or deleted
+ $app->enqueueMessage(Text::sprintf('JGLOBAL_ASSOCIATIONS_CONTENTLANGUAGE_WARNING', $item->lang_code), 'warning');
+ }
+ }
+ }
- try
- {
- $items = $db->loadObjectList('id');
- }
- catch (\RuntimeException $e)
- {
- throw new \Exception($e->getMessage(), 500, $e);
- }
+ $html = LayoutHelper::render('joomla.content.associations', $items);
+ }
- if ($items)
- {
- $app = Factory::getApplication();
- $languages = LanguageHelper::getContentLanguages(array(0, 1));
- $content_languages = array_column($languages, 'lang_code');
-
- foreach ($items as &$item)
- {
- if (in_array($item->lang_code, $content_languages))
- {
- $text = $item->lang_code;
- $url = Route::_('index.php?option=com_weblinks&task=weblink.edit&id=' . (int) $item->id);
- $tooltip = '' . htmlspecialchars($item->language_title, ENT_QUOTES, 'UTF-8') . ' '
- . htmlspecialchars($item->title, ENT_QUOTES, 'UTF-8')
- . ' ' . Text::sprintf('JCATEGORY_SPRINTF', $item->category_title);
- $classes = 'badge bg-secondary';
-
- $item->link = '' . $text . ' '
- . '' . $tooltip . '
';
- }
- else
- {
- // Display warning if Content Language is trashed or deleted
- $app->enqueueMessage(Text::sprintf('JGLOBAL_ASSOCIATIONS_CONTENTLANGUAGE_WARNING', $item->lang_code), 'warning');
- }
- }
- }
-
- $html = LayoutHelper::render('joomla.content.associations', $items);
- }
-
- return $html;
- }
+ return $html;
+ }
}
diff --git a/src/administrator/components/com_weblinks/src/Service/HTML/Icon.php b/src/administrator/components/com_weblinks/src/Service/HTML/Icon.php
index 35ece5b..a209017 100644
--- a/src/administrator/components/com_weblinks/src/Service/HTML/Icon.php
+++ b/src/administrator/components/com_weblinks/src/Service/HTML/Icon.php
@@ -1,4 +1,5 @@
application = $application;
+ }
- /**
- * Service constructor
- *
- * @param CMSApplication $application The application
- *
- * @since 4.0.0
- */
- public function __construct(CMSApplication $application)
- {
- $this->application = $application;
- }
+ /**
+ * Method to generate a link to the create item page for the given category
+ *
+ * @param object $category The category information
+ * @param Registry $params The item parameters
+ * @param array $attribs Optional attributes for the link
+ *
+ * @return string The HTML markup for the create item link
+ *
+ * @since 4.0.0
+ */
+ public static function create($category, $params, $attribs = [])
+ {
+ $uri = Uri::getInstance();
+ $url = 'index.php?option=com_weblinks&task=weblink.add&return=' . base64_encode($uri) . '&w_id=0&catid=' . $category->id;
+ $text = LayoutHelper::render('joomla.content.icons.create', ['params' => $params, 'legacy' => false]);
+ // Add the button classes to the attribs array
+ if (isset($attribs['class'])) {
+ $attribs['class'] .= ' btn btn-primary';
+ } else {
+ $attribs['class'] = 'btn btn-primary';
+ }
- /**
- * Method to generate a link to the create item page for the given category
- *
- * @param object $category The category information
- * @param Registry $params The item parameters
- * @param array $attribs Optional attributes for the link
- *
- * @return string The HTML markup for the create item link
- *
- * @since 4.0.0
- */
- public static function create($category, $params, $attribs = array())
- {
- $uri = Uri::getInstance();
+ $button = HTMLHelper::_('link', Route::_($url), $text, $attribs);
+ $output = '' . $button . ' ';
+ return $output;
+ }
- $url = 'index.php?option=com_weblinks&task=weblink.add&return=' . base64_encode($uri) . '&w_id=0&catid=' . $category->id;
+ /**
+ * Display an edit icon for the weblink.
+ *
+ * This icon will not display in a popup window, nor if the weblink is trashed.
+ * Edit access checks must be performed in the calling code.
+ *
+ * @param object $weblink The weblink information
+ * @param Registry $params The item parameters
+ * @param array $attribs Optional attributes for the link
+ * @param boolean $legacy True to use legacy images, false to use icomoon based graphic
+ *
+ * @return string The HTML for the weblink edit icon.
+ *
+ * @since 4.0.0
+ */
+ public static function edit($weblink, $params, $attribs = [], $legacy = false)
+ {
+ $user = Factory::getApplication()->getIdentity();
+ $uri = Uri::getInstance();
+ // Ignore if in a popup window.
+ if ($params && $params->get('popup')) {
+ return '';
+ }
- $text = LayoutHelper::render('joomla.content.icons.create', array('params' => $params, 'legacy' => false));
+ // Ignore if the state is negative (trashed).
+ if ($weblink->state < 0) {
+ return '';
+ }
- // Add the button classes to the attribs array
- if (isset($attribs['class']))
- {
- $attribs['class'] .= ' btn btn-primary';
- }
- else
- {
- $attribs['class'] = 'btn btn-primary';
- }
+ // Show checked_out icon if the contact is checked out by a different user
+ if (
+ property_exists($weblink, 'checked_out')
+ && property_exists($weblink, 'checked_out_time')
+ && $weblink->checked_out
+ && $weblink->checked_out !== $user->get('id')
+ ) {
+ $checkoutUser = Factory::getUser($weblink->checked_out);
+ $date = HTMLHelper::_('date', $weblink->checked_out_time);
+ $tooltip = Text::sprintf('COM_WEBLINKS_CHECKED_OUT_BY', $checkoutUser->name)
+ . ' ' . $date;
+ $text = LayoutHelper::render('joomla.content.icons.edit_lock', ['contact' => $weblink, 'tooltip' => $tooltip, 'legacy' => $legacy]);
+ $attribs['aria-describedby'] = 'editweblink-' . (int) $weblink->id;
+ $output = HTMLHelper::_('link', '#', $text, $attribs);
+ return $output;
+ }
- $button = HTMLHelper::_('link', Route::_($url), $text, $attribs);
+ $weblinkUrl = RouteHelper::getWeblinkRoute($weblink->slug, $weblink->catid, $weblink->language);
+ $url = $weblinkUrl . '&task=weblink.edit&w_id=' . $weblink->id . '&return=' . base64_encode($uri);
+ if ((int) $weblink->state === 0) {
+ $tooltip = Text::_('COM_WEBLINKS_EDIT_UNPUBLISHED_WEBLINK');
+ } else {
+ $tooltip = Text::_('COM_WEBLINKS_EDIT_PUBLISHED_WEBLINK');
+ }
- $output = '' . $button . ' ';
+ $nowDate = strtotime(Factory::getDate());
+ $icon = $weblink->state ? 'edit' : 'eye-slash';
- return $output;
- }
+ if (
+ ($weblink->publish_up !== null && strtotime($weblink->publish_up) > $nowDate)
+ || ($weblink->publish_down !== null && strtotime($weblink->publish_down) < $nowDate
+ && $weblink->publish_down !== Factory::getDbo()->getNullDate())
+ ) {
+ $icon = 'eye-slash';
+ }
- /**
- * Display an edit icon for the weblink.
- *
- * This icon will not display in a popup window, nor if the weblink is trashed.
- * Edit access checks must be performed in the calling code.
- *
- * @param object $weblink The weblink information
- * @param Registry $params The item parameters
- * @param array $attribs Optional attributes for the link
- * @param boolean $legacy True to use legacy images, false to use icomoon based graphic
- *
- * @return string The HTML for the weblink edit icon.
- *
- * @since 4.0.0
- */
- public static function edit($weblink, $params, $attribs = array(), $legacy = false)
- {
- $user = Factory::getApplication()->getIdentity();
- $uri = Uri::getInstance();
-
- // Ignore if in a popup window.
- if ($params && $params->get('popup'))
- {
- return '';
- }
-
- // Ignore if the state is negative (trashed).
- if ($weblink->state < 0)
- {
- return '';
- }
-
- // Show checked_out icon if the contact is checked out by a different user
- if (property_exists($weblink, 'checked_out')
- && property_exists($weblink, 'checked_out_time')
- && $weblink->checked_out
- && $weblink->checked_out !== $user->get('id'))
- {
- $checkoutUser = Factory::getUser($weblink->checked_out);
- $date = HTMLHelper::_('date', $weblink->checked_out_time);
- $tooltip = Text::sprintf('COM_WEBLINKS_CHECKED_OUT_BY', $checkoutUser->name)
- . ' ' . $date;
-
- $text = LayoutHelper::render('joomla.content.icons.edit_lock', array('contact' => $weblink, 'tooltip' => $tooltip, 'legacy' => $legacy));
-
- $attribs['aria-describedby'] = 'editweblink-' . (int) $weblink->id;
- $output = HTMLHelper::_('link', '#', $text, $attribs);
-
- return $output;
- }
-
- $weblinkUrl = RouteHelper::getWeblinkRoute($weblink->slug, $weblink->catid, $weblink->language);
- $url = $weblinkUrl . '&task=weblink.edit&w_id=' . $weblink->id . '&return=' . base64_encode($uri);
-
- if ((int) $weblink->state === 0)
- {
- $tooltip = Text::_('COM_WEBLINKS_EDIT_UNPUBLISHED_WEBLINK');
- }
- else
- {
- $tooltip = Text::_('COM_WEBLINKS_EDIT_PUBLISHED_WEBLINK');
- }
-
- $nowDate = strtotime(Factory::getDate());
- $icon = $weblink->state ? 'edit' : 'eye-slash';
-
- if (($weblink->publish_up !== null && strtotime($weblink->publish_up) > $nowDate)
- || ($weblink->publish_down !== null && strtotime($weblink->publish_down) < $nowDate
- && $weblink->publish_down !== Factory::getDbo()->getNullDate()))
- {
- $icon = 'eye-slash';
- }
-
- $aria_described = 'editweblink-' . (int) $weblink->id;
-
- $text = ' ';
- $text .= Text::_('JGLOBAL_EDIT');
- $text .= '' . $tooltip . '
';
-
- $attribs['aria-describedby'] = $aria_described;
- $output = HTMLHelper::_('link', Route::_($url), $text, $attribs);
-
- return $output;
- }
+ $aria_described = 'editweblink-' . (int) $weblink->id;
+ $text = ' ';
+ $text .= Text::_('JGLOBAL_EDIT');
+ $text .= '' . $tooltip . '
';
+ $attribs['aria-describedby'] = $aria_described;
+ $output = HTMLHelper::_('link', Route::_($url), $text, $attribs);
+ return $output;
+ }
}
diff --git a/src/administrator/components/com_weblinks/src/Table/WeblinkTable.php b/src/administrator/components/com_weblinks/src/Table/WeblinkTable.php
index b43612b..b23d59b 100644
--- a/src/administrator/components/com_weblinks/src/Table/WeblinkTable.php
+++ b/src/administrator/components/com_weblinks/src/Table/WeblinkTable.php
@@ -1,4 +1,5 @@
typeAlias = 'com_weblinks.weblink';
+ protected $_supportNullValue = true;
+ /**
+ * Ensure the params and metadata in json encoded in the bind method
+ *
+ * @var array
+ * @since 3.4
+ */
+ protected $_jsonEncode = ['params', 'metadata', 'images'];
+ /**
+ * Constructor
+ *
+ * @param \JDatabaseDriver &$db A database connector object
+ *
+ * @since 1.5
+ */
+ public function __construct($db)
+ {
+ $this->typeAlias = 'com_weblinks.weblink';
+ parent::__construct('#__weblinks', 'id', $db);
+ // Set the published column alias
+ $this->setColumnAlias('published', 'state');
+ }
- parent::__construct('#__weblinks', 'id', $db);
+ /**
+ * Overload the store method for the Weblinks table.
+ *
+ * @param boolean $updateNulls Toggle whether null values should be updated.
+ *
+ * @return boolean True on success, false on failure.
+ *
+ * @since 1.6
+ */
+ public function store($updateNulls = true)
+ {
+ $date = Factory::getDate()->toSql();
+ $user = Factory::getApplication()->getIdentity();
+ $this->modified = $date;
+ if ($this->id) {
+ // Existing item
+ $this->modified_by = $user->id;
+ $this->modified = $date;
+ } else {
+ // New weblink. A weblink 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;
+ }
- // Set the published column alias
- $this->setColumnAlias('published', 'state');
- }
+ if (empty($this->created_by)) {
+ $this->created_by = $user->id;
+ }
- /**
- * Overload the store method for the Weblinks table.
- *
- * @param boolean $updateNulls Toggle whether null values should be updated.
- *
- * @return boolean True on success, false on failure.
- *
- * @since 1.6
- */
- public function store($updateNulls = true)
- {
- $date = Factory::getDate()->toSql();
- $user = Factory::getApplication()->getIdentity();
+ if (!(int) $this->modified) {
+ $this->modified = $date;
+ }
- $this->modified = $date;
+ if (empty($this->modified_by)) {
+ $this->modified_by = $user->id;
+ }
- if ($this->id)
- {
- // Existing item
- $this->modified_by = $user->id;
- $this->modified = $date;
- }
- else
- {
- // New weblink. A weblink 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->hits)) {
+ $this->hits = 0;
+ }
+ }
- if (empty($this->created_by))
- {
- $this->created_by = $user->id;
- }
+ // Set publish_up to null if not set
+ if (!$this->publish_up) {
+ $this->publish_up = null;
+ }
- if (!(int) $this->modified)
- {
- $this->modified = $date;
- }
+ // Set publish_down to null if not set
+ if (!$this->publish_down) {
+ $this->publish_down = null;
+ }
- if (empty($this->modified_by))
- {
- $this->modified_by = $user->id;
- }
+ // Verify that the alias is unique
+ $table = new WeblinkTable($this->getDbo());
- if (empty($this->hits))
- {
- $this->hits = 0;
- }
- }
+ if (
+ $table->load(['language' => $this->language, 'alias' => $this->alias, 'catid' => (int) $this->catid])
+ && ($table->id != $this->id || $this->id == 0)
+ ) {
+ $this->setError(Text::_('COM_WEBLINKS_ERROR_UNIQUE_ALIAS'));
+ return false;
+ }
- // Set publish_up to null if not set
- if (!$this->publish_up)
- {
- $this->publish_up = null;
- }
+ // Convert IDN urls to punycode
+ $this->url = PunycodeHelper::urlToPunycode($this->url);
+ return parent::store($updateNulls);
+ }
- // Set publish_down to null if not set
- if (!$this->publish_down)
- {
- $this->publish_down = null;
- }
+ /**
+ * Overloaded check method to ensure data integrity.
+ *
+ * @return boolean True on success.
+ *
+ * @since 1.5
+ */
+ public function check()
+ {
+ if (InputFilter::checkAttribute(['href', $this->url])) {
+ $this->setError(Text::_('COM_WEBLINKS_ERR_TABLES_PROVIDE_URL'));
+ return false;
+ }
- // Verify that the alias is unique
- $table = new WeblinkTable($this->getDbo());
+ // Check for valid name
+ if (trim($this->title) == '') {
+ $this->setError(Text::_('COM_WEBLINKS_ERR_TABLES_TITLE'));
+ return false;
+ }
- if ($table->load(array('language' => $this->language, 'alias' => $this->alias, 'catid' => (int) $this->catid))
- && ($table->id != $this->id || $this->id == 0))
- {
- $this->setError(Text::_('COM_WEBLINKS_ERROR_UNIQUE_ALIAS'));
+ // Check for existing name
+ $db = $this->getDbo();
+ $query = $db->getQuery(true)
+ ->select($db->quoteName('id'))
+ ->from($db->quoteName('#__weblinks'))
+ ->where($db->quoteName('title') . ' = :title')
+ ->where($db->quoteName('language') . ' = :language')
+ ->where($db->quoteName('catid') . ' = :catid')
+ ->bind(':title', $this->title)
+ ->bind(':language', $this->language)
+ ->bind(':catid', $this->catid, ParameterType::INTEGER);
+ $db->setQuery($query);
+ $xid = (int) $db->loadResult();
+ if ($xid && $xid != (int) $this->id) {
+ $this->setError(Text::_('COM_WEBLINKS_ERR_TABLES_NAME'));
+ return false;
+ }
- return false;
- }
+ if (empty($this->alias)) {
+ $this->alias = $this->title;
+ }
- // Convert IDN urls to punycode
- $this->url = PunycodeHelper::urlToPunycode($this->url);
+ $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 parent::store($updateNulls);
- }
+ // 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;
+ }
- /**
- * Overloaded check method to ensure data integrity.
- *
- * @return boolean True on success.
- *
- * @since 1.5
- */
- public function check()
- {
- if (InputFilter::checkAttribute(array('href', $this->url)))
- {
- $this->setError(Text::_('COM_WEBLINKS_ERR_TABLES_PROVIDE_URL'));
+ /*
+ * Clean up keywords -- eliminate extra spaces between phrases
+ * and cr (\r) and lf (\n) characters from string
+ */
+ if (!empty($this->metakey)) {
+ // Array of characters to remove
+ $bad_characters = ["\n", "\r", "\"", "<", ">"];
+ $after_clean = StringHelper::str_ireplace($bad_characters, "", $this->metakey);
+ $keys = explode(',', $after_clean);
+ $clean_keys = [];
+ foreach ($keys as $key) {
+ // Ignore blank keywords
+ if (trim($key)) {
+ $clean_keys[] = trim($key);
+ }
+ }
- return false;
- }
+ // Put array back together delimited by ", "
+ $this->metakey = implode(", ", $clean_keys);
+ }
- // Check for valid name
- if (trim($this->title) == '')
- {
- $this->setError(Text::_('COM_WEBLINKS_ERR_TABLES_TITLE'));
+ /**
+ * Ensure any new items have compulsory fields set. This is needed for things like
+ * frontend editing where we don't show all the fields or using some kind of API
+ */
+ if (!$this->id) {
+ if (!isset($this->xreference)) {
+ $this->xreference = '';
+ }
- return false;
- }
+ if (!isset($this->metakey)) {
+ $this->metakey = '';
+ }
- // Check for existing name
- $db = $this->getDbo();
+ if (!isset($this->metadesc)) {
+ $this->metadesc = '';
+ }
- $query = $db->getQuery(true)
- ->select($db->quoteName('id'))
- ->from($db->quoteName('#__weblinks'))
- ->where($db->quoteName('title') . ' = :title')
- ->where($db->quoteName('language') . ' = :language')
- ->where($db->quoteName('catid') . ' = :catid')
- ->bind(':title', $this->title)
- ->bind(':language', $this->language)
- ->bind(':catid', $this->catid, ParameterType::INTEGER);
- $db->setQuery($query);
+ if (!isset($this->images)) {
+ $this->images = '{}';
+ }
- $xid = (int) $db->loadResult();
+ if (!isset($this->metadata)) {
+ $this->metadata = '{}';
+ }
- if ($xid && $xid != (int) $this->id)
- {
- $this->setError(Text::_('COM_WEBLINKS_ERR_TABLES_NAME'));
+ if (!isset($this->params)) {
+ $this->params = '{}';
+ }
+ }
- return false;
- }
+ return parent::check();
+ }
- if (empty($this->alias))
- {
- $this->alias = $this->title;
- }
-
- $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 ((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
- */
- if (!empty($this->metakey))
- {
- // Array of characters to remove
- $bad_characters = array("\n", "\r", "\"", "<", ">");
- $after_clean = StringHelper::str_ireplace($bad_characters, "", $this->metakey);
- $keys = explode(',', $after_clean);
- $clean_keys = array();
-
- foreach ($keys as $key)
- {
- // Ignore blank keywords
- if (trim($key))
- {
- $clean_keys[] = trim($key);
- }
- }
-
- // Put array back together delimited by ", "
- $this->metakey = implode(", ", $clean_keys);
- }
-
- /**
- * Ensure any new items have compulsory fields set. This is needed for things like
- * frontend editing where we don't show all the fields or using some kind of API
- */
- if (!$this->id)
- {
- if (!isset($this->xreference))
- {
- $this->xreference = '';
- }
-
- if (!isset($this->metakey))
- {
- $this->metakey = '';
- }
-
- if (!isset($this->metadesc))
- {
- $this->metadesc = '';
- }
-
- if (!isset($this->images))
- {
- $this->images = '{}';
- }
-
- if (!isset($this->metadata))
- {
- $this->metadata = '{}';
- }
-
- if (!isset($this->params))
- {
- $this->params = '{}';
- }
- }
-
- return parent::check();
- }
-
- /**
- * Get the type alias for the history table
- *
- * @return string The alias as described above
- *
- * @since 4.0.0
- */
- public function getTypeAlias()
- {
- return $this->typeAlias;
- }
+ /**
+ * Get the type alias for the history table
+ *
+ * @return string The alias as described above
+ *
+ * @since 4.0.0
+ */
+ public function getTypeAlias()
+ {
+ return $this->typeAlias;
+ }
}
diff --git a/src/administrator/components/com_weblinks/src/View/Weblink/HtmlView.php b/src/administrator/components/com_weblinks/src/View/Weblink/HtmlView.php
index 0eb467c..ce3826c 100644
--- a/src/administrator/components/com_weblinks/src/View/Weblink/HtmlView.php
+++ b/src/administrator/components/com_weblinks/src/View/Weblink/HtmlView.php
@@ -1,4 +1,5 @@
state = $this->get('State');
- $this->item = $this->get('Item');
- $this->form = $this->get('Form');
+ /**
+ * Display the view.
+ *
+ * @param string $tpl The name of the template file to parse; automatically searches through the template paths.
+ *
+ * @return mixed A string if successful, otherwise an Error object.
+ */
+ public function display($tpl = null)
+ {
+ $this->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 GenericDataException(implode("\n", $errors), 500);
- }
+ // Check for errors.
+ if (count($errors = $this->get('Errors'))) {
+ throw new GenericDataException(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');
+ // 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 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);
- }
+ // Only allow to select tags with All language or with the forced language.
+ $this->form->setFieldAttribute('tags', 'language', '*,' . $forcedLanguage);
+ }
- $this->addToolbar();
+ $this->addToolbar();
- parent::display($tpl);
- }
+ parent::display($tpl);
+ }
- /**
- * Add the page title and toolbar.
- *
- * @return void
- *
- * @since 1.6
- */
- protected function addToolbar()
- {
- $app = Factory::getApplication();
- $app->input->set('hidemainmenu', true);
+ /**
+ * Add the page title and toolbar.
+ *
+ * @return void
+ *
+ * @since 1.6
+ */
+ protected function addToolbar()
+ {
+ $app = Factory::getApplication();
+ $app->input->set('hidemainmenu', true);
- $user = $this->getCurrentUser();
- $isNew = ($this->item->id == 0);
- $checkedOut = $this->item->checked_out && $this->item->checked_out !== $user->get('id');
+ $user = $this->getCurrentUser();
+ $isNew = ($this->item->id == 0);
+ $checkedOut = $this->item->checked_out && $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_weblinks', 'category', $this->item->catid);
+ // Since we don't track these assets at the item level, use the category id.
+ $canDo = ContentHelper::getActions('com_weblinks', 'category', $this->item->catid);
- ToolbarHelper::title($isNew ? Text::_('COM_WEBLINKS_MANAGER_WEBLINK_NEW') : Text::_('COM_WEBLINKS_MANAGER_WEBLINK_EDIT'), 'link weblinks');
+ ToolbarHelper::title($isNew ? Text::_('COM_WEBLINKS_MANAGER_WEBLINK_NEW') : Text::_('COM_WEBLINKS_MANAGER_WEBLINK_EDIT'), 'link weblinks');
- // Build the actions for new and existing records.
- if ($isNew)
- {
- // For new records, check the create permission.
- if (count($user->getAuthorisedCategories('com_weblinks', 'core.create')) > 0)
- {
- ToolbarHelper::apply('weblink.apply');
+ // Build the actions for new and existing records.
+ if ($isNew) {
+ // For new records, check the create permission.
+ if (count($user->getAuthorisedCategories('com_weblinks', 'core.create')) > 0) {
+ ToolbarHelper::apply('weblink.apply');
- ToolbarHelper::saveGroup(
- [
- ['save', 'weblink.save'],
- ['save2new', 'weblink.save2new']
- ],
- 'btn-success'
- );
- }
+ ToolbarHelper::saveGroup(
+ [
+ ['save', 'weblink.save'],
+ ['save2new', 'weblink.save2new'],
+ ],
+ 'btn-success'
+ );
+ }
- ToolbarHelper::cancel('weblink.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 == $user->id);
+ ToolbarHelper::cancel('weblink.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 == $user->id);
- $toolbarButtons = [];
+ $toolbarButtons = [];
- // Can't save the record if it's checked out and editable
- if (!$checkedOut && $itemEditable)
- {
- ToolbarHelper::apply('weblink.apply');
+ // Can't save the record if it's checked out and editable
+ if (!$checkedOut && $itemEditable) {
+ ToolbarHelper::apply('weblink.apply');
- $toolbarButtons[] = ['save', 'weblink.save'];
+ $toolbarButtons[] = ['save', 'weblink.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', 'weblink.save2new'];
- }
- }
+ // 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', 'weblink.save2new'];
+ }
+ }
- // If checked out, we can still save
- if ($canDo->get('core.create'))
- {
- $toolbarButtons[] = ['save2copy', 'weblink.save2copy'];
- }
+ // If checked out, we can still save
+ if ($canDo->get('core.create')) {
+ $toolbarButtons[] = ['save2copy', 'weblink.save2copy'];
+ }
- ToolbarHelper::saveGroup(
- $toolbarButtons,
- 'btn-success'
- );
+ ToolbarHelper::saveGroup(
+ $toolbarButtons,
+ 'btn-success'
+ );
- ToolbarHelper::cancel('weblink.cancel', 'JTOOLBAR_CLOSE');
+ ToolbarHelper::cancel('weblink.cancel', 'JTOOLBAR_CLOSE');
- if (ComponentHelper::isEnabled('com_contenthistory') && $this->state->params->get('save_history', 0) && $itemEditable)
- {
- ToolbarHelper::versions('com_weblinks.weblink', $this->item->id);
- }
+ if (ComponentHelper::isEnabled('com_contenthistory') && $this->state->params->get('save_history', 0) && $itemEditable) {
+ ToolbarHelper::versions('com_weblinks.weblink', $this->item->id);
+ }
- if (Associations::isEnabled() && ComponentHelper::isEnabled('com_associations'))
- {
- ToolbarHelper::custom('weblink.editAssociations', 'contract', '', 'JTOOLBAR_ASSOCIATIONS', false, false);
- }
- }
+ if (Associations::isEnabled() && ComponentHelper::isEnabled('com_associations')) {
+ ToolbarHelper::custom('weblink.editAssociations', 'contract', '', 'JTOOLBAR_ASSOCIATIONS', false, false);
+ }
+ }
- ToolbarHelper::help('Components_Weblinks_Links_Edit');
- }
+ ToolbarHelper::help('Components_Weblinks_Links_Edit');
+ }
}
diff --git a/src/administrator/components/com_weblinks/src/View/Weblinks/HtmlView.php b/src/administrator/components/com_weblinks/src/View/Weblinks/HtmlView.php
index ce87434..9d2d036 100644
--- a/src/administrator/components/com_weblinks/src/View/Weblinks/HtmlView.php
+++ b/src/administrator/components/com_weblinks/src/View/Weblinks/HtmlView.php
@@ -1,4 +1,5 @@
state = $this->get('State');
- $this->items = $this->get('Items');
- $this->pagination = $this->get('Pagination');
- $this->filterForm = $this->get('FilterForm');
- $this->activeFilters = $this->get('ActiveFilters');
+ /**
+ * Display the view.
+ *
+ * @param string $tpl The name of the template file to parse; automatically searches through the template paths.
+ *
+ * @return mixed A string if successful, otherwise an Error object.
+ */
+ public function display($tpl = null)
+ {
+ $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 GenericDataException(implode("\n", $errors), 500);
- }
+ // Check for errors.
+ if (count($errors = $this->get('Errors'))) {
+ throw new GenericDataException(implode("\n", $errors), 500);
+ }
- if (!\count($this->items) && $this->isEmptyState = $this->get('IsEmptyState'))
- {
- $this->setLayout('emptystate');
- }
+ if (!\count($this->items) && $this->isEmptyState = $this->get('IsEmptyState')) {
+ $this->setLayout('emptystate');
+ }
- // We don't need toolbar in the modal layout.
- if ($this->getLayout() !== 'modal')
- {
- $this->addToolbar();
- }
- 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 an hidden field.
- $languageXml = new \SimpleXMLElement(' ');
- $this->filterForm->setField($languageXml, 'filter', true);
+ // We don't need toolbar in the modal layout.
+ if ($this->getLayout() !== 'modal') {
+ $this->addToolbar();
+ } 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 an hidden field.
+ $languageXml = new \SimpleXMLElement(' ');
+ $this->filterForm->setField($languageXml, 'filter', true);
- // Also, unset the active language filter so the search tools is not open by default with this filter.
- unset($this->activeFilters['language']);
+ // 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');
- }
- }
+ // 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);
- }
+ parent::display($tpl);
+ }
- /**
- * Add the page title and toolbar.
- *
- * @return void
- *
- * @since 1.6
- */
- protected function addToolbar()
- {
- $canDo = ContentHelper::getActions('com_weblinks', 'category', $this->state->get('filter.category_id'));
- $user = $this->getCurrentUser();
+ /**
+ * Add the page title and toolbar.
+ *
+ * @return void
+ *
+ * @since 1.6
+ */
+ protected function addToolbar()
+ {
+ $canDo = ContentHelper::getActions('com_weblinks', 'category', $this->state->get('filter.category_id'));
+ $user = $this->getCurrentUser();
- // Get the toolbar object instance
- $toolbar = Toolbar::getInstance('toolbar');
+ // Get the toolbar object instance
+ $toolbar = Toolbar::getInstance('toolbar');
- ToolbarHelper::title(Text::_('COM_WEBLINKS_MANAGER_WEBLINKS'), 'link weblinks');
+ ToolbarHelper::title(Text::_('COM_WEBLINKS_MANAGER_WEBLINKS'), 'link weblinks');
- if ($canDo->get('core.create') || \count($user->getAuthorisedCategories('com_weblinks', 'core.create')) > 0)
- {
- ToolbarHelper::addNew('weblink.add');
- }
+ if ($canDo->get('core.create') || \count($user->getAuthorisedCategories('com_weblinks', 'core.create')) > 0) {
+ ToolbarHelper::addNew('weblink.add');
+ }
- if (!$this->isEmptyState && $canDo->get('core.edit.state'))
- {
- $dropdown = $toolbar->dropdownButton('status-group')
- ->text('JTOOLBAR_CHANGE_STATUS')
- ->toggleSplit(false)
- ->icon('icon-ellipsis-h')
- ->buttonClass('btn btn-action')
- ->listCheck(true);
+ if (!$this->isEmptyState && $canDo->get('core.edit.state')) {
+ $dropdown = $toolbar->dropdownButton('status-group')
+ ->text('JTOOLBAR_CHANGE_STATUS')
+ ->toggleSplit(false)
+ ->icon('icon-ellipsis-h')
+ ->buttonClass('btn btn-action')
+ ->listCheck(true);
- $childBar = $dropdown->getChildToolbar();
+ $childBar = $dropdown->getChildToolbar();
- $childBar->publish('weblinks.publish')->listCheck(true);
+ $childBar->publish('weblinks.publish')->listCheck(true);
- $childBar->unpublish('weblinks.unpublish')->listCheck(true);
+ $childBar->unpublish('weblinks.unpublish')->listCheck(true);
- $childBar->archive('weblinks.archive')->listCheck(true);
+ $childBar->archive('weblinks.archive')->listCheck(true);
- if ($user->authorise('core.admin'))
- {
- $childBar->checkin('weblinks.checkin')->listCheck(true);
- }
+ if ($user->authorise('core.admin')) {
+ $childBar->checkin('weblinks.checkin')->listCheck(true);
+ }
- if ($this->state->get('filter.published') != -2)
- {
- $childBar->trash('weblinks.trash')->listCheck(true);
- }
+ if ($this->state->get('filter.published') != -2) {
+ $childBar->trash('weblinks.trash')->listCheck(true);
+ }
- // Add a batch button
- if ($user->authorise('core.create', 'com_weblinks')
- && $user->authorise('core.edit', 'com_weblinks')
- && $user->authorise('core.edit.state', 'com_weblinks'))
- {
- $childBar->popupButton('batch')
- ->text('JTOOLBAR_BATCH')
- ->selector('collapseModal')
- ->listCheck(true);
- }
- }
+ // Add a batch button
+ if (
+ $user->authorise('core.create', 'com_weblinks')
+ && $user->authorise('core.edit', 'com_weblinks')
+ && $user->authorise('core.edit.state', 'com_weblinks')
+ ) {
+ $childBar->popupButton('batch')
+ ->text('JTOOLBAR_BATCH')
+ ->selector('collapseModal')
+ ->listCheck(true);
+ }
+ }
- if (!$this->isEmptyState && $this->state->get('filter.published') == -2 && $canDo->get('core.delete'))
- {
- $toolbar->delete('weblinks.delete')
- ->text('JTOOLBAR_EMPTY_TRASH')
- ->message('JGLOBAL_CONFIRM_DELETE')
- ->listCheck(true);
- }
+ if (!$this->isEmptyState && $this->state->get('filter.published') == -2 && $canDo->get('core.delete')) {
+ $toolbar->delete('weblinks.delete')
+ ->text('JTOOLBAR_EMPTY_TRASH')
+ ->message('JGLOBAL_CONFIRM_DELETE')
+ ->listCheck(true);
+ }
- if ($user->authorise('core.admin', 'com_weblinks') || $user->authorise('core.options', 'com_weblinks'))
- {
- ToolbarHelper::preferences('com_weblinks');
- }
+ if ($user->authorise('core.admin', 'com_weblinks') || $user->authorise('core.options', 'com_weblinks')) {
+ ToolbarHelper::preferences('com_weblinks');
+ }
- ToolbarHelper::help('Components_Weblinks_Links');
- }
+ ToolbarHelper::help('Components_Weblinks_Links');
+ }
}
diff --git a/src/administrator/components/com_weblinks/tmpl/weblink/edit.php b/src/administrator/components/com_weblinks/tmpl/weblink/edit.php
index fff3838..4d1b292 100644
--- a/src/administrator/components/com_weblinks/tmpl/weblink/edit.php
+++ b/src/administrator/components/com_weblinks/tmpl/weblink/edit.php
@@ -1,4 +1,5 @@
input;
-
$assoc = Associations::isEnabled();
-
// Fieldsets to not automatically render by /layouts/joomla/edit/params.php
$this->ignore_fieldsets = array('details', 'images', 'item_associations', 'jmetadata');
$this->useCoreUI = true;
-
// In case of modal
$isModal = $input->get('layout') == 'modal' ? true : false;
$layout = $isModal ? 'modal' : 'edit';
@@ -35,81 +32,87 @@ $tmpl = $isModal || $input->get('tmpl', '', 'cmd') === 'component' ? '&tmpl=c
diff --git a/src/administrator/components/com_weblinks/tmpl/weblink/edit_associations.php b/src/administrator/components/com_weblinks/tmpl/weblink/edit_associations.php
index 731f5d3..4c9be9f 100644
--- a/src/administrator/components/com_weblinks/tmpl/weblink/edit_associations.php
+++ b/src/administrator/components/com_weblinks/tmpl/weblink/edit_associations.php
@@ -1,4 +1,5 @@
form->getFieldsets('params'); ?>
- $fieldSet) : ?>
-
- description) && trim($fieldSet->description)) : ?>
- ' . $this->escape(Text::_($fieldSet->description)) . ''; ?>
-
- form->getFieldset($name) as $field) : ?>
-
-
label; ?>
-
input; ?>
-
-
-
-
+ $fieldSet) :
+ ?>
+
+ description) && trim($fieldSet->description)) :
+ ?>
+ ' . $this->escape(Text::_($fieldSet->description)) . ''; ?>
+
+ form->getFieldset($name) as $field) :
+ ?>
+
+
label; ?>
+
input; ?>
+
+
+
+
diff --git a/src/administrator/components/com_weblinks/tmpl/weblink/modal.php b/src/administrator/components/com_weblinks/tmpl/weblink/modal.php
index 0dbf7be..dbb905f 100644
--- a/src/administrator/components/com_weblinks/tmpl/weblink/modal.php
+++ b/src/administrator/components/com_weblinks/tmpl/weblink/modal.php
@@ -1,4 +1,5 @@
'bottom'));
-
// @deprecated 4.0 the function parameter, the inline js and the buttons are not needed since 3.7.0.
$function = Factory::getApplication()->input->getCmd('function', 'jEditWeblink_' . (int) $this->item->id);
-
// Function to update input title when changed
Factory::getDocument()->addScriptDeclaration('
function jEditWeblinkModal() {
@@ -30,6 +30,6 @@ Factory::getDocument()->addScriptDeclaration('
diff --git a/src/administrator/components/com_weblinks/tmpl/weblink/modal_associations.php b/src/administrator/components/com_weblinks/tmpl/weblink/modal_associations.php
index 731f5d3..4c9be9f 100644
--- a/src/administrator/components/com_weblinks/tmpl/weblink/modal_associations.php
+++ b/src/administrator/components/com_weblinks/tmpl/weblink/modal_associations.php
@@ -1,4 +1,5 @@
form->getFieldsets('params'); ?>
- $fieldSet) : ?>
-
- description) && trim($fieldSet->description)) : ?>
- ' . $this->escape(Text::_($fieldSet->description)) . ''; ?>
-
- form->getFieldset($name) as $field) : ?>
-
-
label; ?>
-
input; ?>
-
-
-
-
+ $fieldSet) :
+ ?>
+
+ description) && trim($fieldSet->description)) :
+ ?>
+ ' . $this->escape(Text::_($fieldSet->description)) . ''; ?>
+
+ form->getFieldset($name) as $field) :
+ ?>
+
+
label; ?>
+
input; ?>
+
+
+
+
diff --git a/src/administrator/components/com_weblinks/tmpl/weblinks/default.php b/src/administrator/components/com_weblinks/tmpl/weblinks/default.php
index f0a9e62..b423595 100644
--- a/src/administrator/components/com_weblinks/tmpl/weblinks/default.php
+++ b/src/administrator/components/com_weblinks/tmpl/weblinks/default.php
@@ -1,4 +1,5 @@
getIdentity();
$userId = $user->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_weblinks&task=weblinks.saveOrderAjax&tmpl=component';
- HTMLHelper::_('draggablelist.draggable');
+if ($saveOrder && !empty($this->items)) {
+ $saveOrderingUrl = 'index.php?option=com_weblinks&task=weblinks.saveOrderAjax&tmpl=component';
+ HTMLHelper::_('draggablelist.draggable');
}
?>
diff --git a/src/administrator/components/com_weblinks/tmpl/weblinks/default_batch_body.php b/src/administrator/components/com_weblinks/tmpl/weblinks/default_batch_body.php
index 6b5dab6..e0f8e31 100644
--- a/src/administrator/components/com_weblinks/tmpl/weblinks/default_batch_body.php
+++ b/src/administrator/components/com_weblinks/tmpl/weblinks/default_batch_body.php
@@ -1,4 +1,5 @@
state->get('filter.published');
?>
diff --git a/src/administrator/components/com_weblinks/tmpl/weblinks/default_batch_footer.php b/src/administrator/components/com_weblinks/tmpl/weblinks/default_batch_footer.php
index 05744dc..51fcc78 100644
--- a/src/administrator/components/com_weblinks/tmpl/weblinks/default_batch_footer.php
+++ b/src/administrator/components/com_weblinks/tmpl/weblinks/default_batch_footer.php
@@ -1,4 +1,5 @@
-
+
-
+
diff --git a/src/administrator/components/com_weblinks/tmpl/weblinks/emptystate.php b/src/administrator/components/com_weblinks/tmpl/weblinks/emptystate.php
index 8091dd2..5820930 100644
--- a/src/administrator/components/com_weblinks/tmpl/weblinks/emptystate.php
+++ b/src/administrator/components/com_weblinks/tmpl/weblinks/emptystate.php
@@ -1,4 +1,5 @@
'COM_WEBLINKS',
- 'formURL' => 'index.php?option=com_weblinks',
- 'helpURL' => 'https://docs.joomla.org/Special:MyLanguage/Help4.x:Weblinks',
- 'icon' => 'icon-globe weblink',
+ 'textPrefix' => 'COM_WEBLINKS',
+ 'formURL' => 'index.php?option=com_weblinks',
+ 'helpURL' => 'https://docs.joomla.org/Special:MyLanguage/Help4.x:Weblinks',
+ 'icon' => 'icon-globe weblink',
];
-
$user = Factory::getApplication()->getIdentity();
-
-if ($user->authorise('core.create', 'com_weblinks') || count($user->getAuthorisedCategories('com_weblinks', 'core.create')) > 0)
-{
- $displayData['createURL'] = 'index.php?option=com_weblinks&task=weblink.add';
+if ($user->authorise('core.create', 'com_weblinks') || count($user->getAuthorisedCategories('com_weblinks', 'core.create')) > 0) {
+ $displayData['createURL'] = 'index.php?option=com_weblinks&task=weblink.add';
}
-echo LayoutHelper::render('joomla.content.emptystate', $displayData);
\ No newline at end of file
+echo LayoutHelper::render('joomla.content.emptystate', $displayData);
diff --git a/src/administrator/components/com_weblinks/tmpl/weblinks/modal.php b/src/administrator/components/com_weblinks/tmpl/weblinks/modal.php
index 05081f4..82c76d9 100644
--- a/src/administrator/components/com_weblinks/tmpl/weblinks/modal.php
+++ b/src/administrator/components/com_weblinks/tmpl/weblinks/modal.php
@@ -1,4 +1,5 @@
isClient('site'))
-{
- Session::checkToken('get') or die(Text::_('JINVALID_TOKEN'));
+if ($app->isClient('site')) {
+ Session::checkToken('get') or die(Text::_('JINVALID_TOKEN'));
}
HTMLHelper::_('behavior.multiselect');
-
$this->document->getWebAssetManager()
- ->registerAndUseScript('com_weblinks.admin-weblinks-modal', 'media/com_weblinks/js/admin-weblinks-modal.js', [], ['defer' => true], ['core']);
-
+ ->registerAndUseScript('com_weblinks.admin-weblinks-modal', 'media/com_weblinks/js/admin-weblinks-modal.js', [], ['defer' => true], ['core']);
$function = $app->input->getCmd('function', 'jSelectWeblink');
$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);
$multilang = Multilanguage::isEnabled();
-
-if (!empty($editor))
-{
- // This view is used also in com_menus. Load the xtd script only if the editor is set!
- $this->document->addScriptOptions('xtd-weblinks', array('editor' => $editor));
- $onclick = "jSelectWeblink";
+if (!empty($editor)) {
+// This view is used also in com_menus. Load the xtd script only if the editor is set!
+ $this->document->addScriptOptions('xtd-weblinks', array('editor' => $editor));
+ $onclick = "jSelectWeblink";
}
$iconStates = array(
- -2 => 'icon-trash',
- 0 => 'icon-unpublish',
- 1 => 'icon-publish',
- 2 => 'icon-archive',
+ -2 => 'icon-trash',
+ 0 => 'icon-unpublish',
+ 1 => 'icon-publish',
+ 2 => 'icon-archive',
);
?>
diff --git a/src/administrator/components/com_weblinks/weblinks.xml b/src/administrator/components/com_weblinks/weblinks.xml
index e36615c..f0f995e 100644
--- a/src/administrator/components/com_weblinks/weblinks.xml
+++ b/src/administrator/components/com_weblinks/weblinks.xml
@@ -1,68 +1,69 @@
-
-
- com_weblinks
- Joomla! Project
- ##DATE##
- (C) 2005 - ##YEAR## Open Source Matters. All rights reserved.
- GNU General Public License version 2 or later; see LICENSE.txt
- admin@joomla.org
- www.joomla.org
- ##VERSION##
- COM_WEBLINKS_XML_DESCRIPTION
- script.php
- Joomla\Component\Weblinks
-
-
-
- sql/install.mysql.sql
- sql/install.postgresql.sql
-
-
-
-
- sql/uninstall.mysql.sql
- sql/uninstall.postgresql.sql
-
-
-
-
- sql/updates/mysql
- sql/updates/postgresql
-
-
-
-
- ##MEDIA_FILES##
-
-
-
- ##FRONTEND_COMPONENT_FILES##
-
-
- ##FRONTEND_LANGUAGE_FILES##
-
-
- com_weblinks
-
-
- com_weblinks_links
- com_weblinks_categories
- com_weblinks_fields
- com_weblinks_field_groups
-
-
- ##BACKEND_COMPONENT_FILES##
-
-
- ##BACKEND_LANGUAGE_FILES##
-
-
-
-
+
+
+ com_weblinks
+ com_weblinks
+ Joomla! Project
+ ##DATE##
+ (C) 2005 - ##YEAR## Open Source Matters. All rights reserved.
+ GNU General Public License version 2 or later; see LICENSE.txt
+ admin@joomla.org
+ www.joomla.org
+ ##VERSION##
+ COM_WEBLINKS_XML_DESCRIPTION
+ script.php
+ Joomla\Component\Weblinks
+
+
+
+ sql/install.mysql.sql
+ sql/install.postgresql.sql
+
+
+
+
+ sql/uninstall.mysql.sql
+ sql/uninstall.postgresql.sql
+
+
+
+
+ sql/updates/mysql
+ sql/updates/postgresql
+
+
+
+
+ ##MEDIA_FILES##
+
+
+
+ ##FRONTEND_COMPONENT_FILES##
+
+
+ ##FRONTEND_LANGUAGE_FILES##
+
+
+ com_weblinks
+
+
+ com_weblinks_links
+ com_weblinks_categories
+ com_weblinks_fields
+ com_weblinks_field_groups
+
+
+ ##BACKEND_COMPONENT_FILES##
+
+
+ ##BACKEND_LANGUAGE_FILES##
+
+
+
+
diff --git a/src/administrator/manifests/packages/weblinks/script.php b/src/administrator/manifests/packages/weblinks/script.php
index e9a8179..99ab66a 100644
--- a/src/administrator/manifests/packages/weblinks/script.php
+++ b/src/administrator/manifests/packages/weblinks/script.php
@@ -1,4 +1,5 @@
minimumJoomla = '3.6.3';
- $this->minimumPhp = JOOMLA_MINIMUM_PHP;
- }
+ /**
+ * Extension script constructor.
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function __construct()
+ {
+ $this->minimumJoomla = '3.6.3';
+ $this->minimumPhp = JOOMLA_MINIMUM_PHP;
+ }
}
diff --git a/src/components/com_weblinks/helpers/icon.php b/src/components/com_weblinks/helpers/icon.php
index 6150446..567974d 100644
--- a/src/components/com_weblinks/helpers/icon.php
+++ b/src/components/com_weblinks/helpers/icon.php
@@ -1,4 +1,5 @@
create($category, $params);
- }
+ /**
+ * Create a link to create a new weblink
+ *
+ * @param object $category The category information
+ * @param \Joomla\Registry\Registry $params The item parameters
+ *
+ * @return string
+ */
+ public static function create($category, $params)
+ {
+ return self::getIcon()->create($category, $params);
+ }
- /**
- * Create a link to edit an existing weblink
- *
- * @param object $weblink Weblink data
- * @param \Joomla\Registry\Registry $params Item params
- * @param array $attribs Unused
- *
- * @return string
- */
- public static function edit($weblink, $params, $attribs = array())
- {
- return self::getIcon()->edit($weblink, $params, $attribs);
- }
+ /**
+ * Create a link to edit an existing weblink
+ *
+ * @param object $weblink Weblink data
+ * @param \Joomla\Registry\Registry $params Item params
+ * @param array $attribs Unused
+ *
+ * @return string
+ */
+ public static function edit($weblink, $params, $attribs = [])
+ {
+ return self::getIcon()->edit($weblink, $params, $attribs);
+ }
- /**
- * Creates an icon instance.
- *
- * @return \Joomla\Component\Weblinks\Administrator\Service\HTML\Icon
- */
- private static function getIcon()
- {
- return (new \Joomla\Component\Weblinks\Administrator\Service\HTML\Icon(Joomla\CMS\Factory::getApplication()));
- }
+ /**
+ * Creates an icon instance.
+ *
+ * @return \Joomla\Component\Weblinks\Administrator\Service\HTML\Icon
+ */
+ private static function getIcon()
+ {
+ return (new \Joomla\Component\Weblinks\Administrator\Service\HTML\Icon(Joomla\CMS\Factory::getApplication()));
+ }
}
diff --git a/src/components/com_weblinks/helpers/route.php b/src/components/com_weblinks/helpers/route.php
index c239da3..432bcc3 100644
--- a/src/components/com_weblinks/helpers/route.php
+++ b/src/components/com_weblinks/helpers/route.php
@@ -1,4 +1,5 @@
input->getInt('w_id');
+ $vName = $this->input->get('view', 'categories');
+ $this->input->set('view', $vName);
+ if ($this->app->getIdentity()->id || ($this->input->getMethod() == 'POST' && $vName == 'categories')) {
+ $cacheable = false;
+ }
- /**
- * Set the default view name and format from the Request.
- * Note we are using w_id to avoid collisions with the router and the return page.
- * Frontend is a bit messier than the backend.
- */
- $id = $this->input->getInt('w_id');
- $vName = $this->input->get('view', 'categories');
- $this->input->set('view', $vName);
+ $safeurlparams = [
+ 'id' => 'INT',
+ 'limit' => 'UINT',
+ 'limitstart' => 'UINT',
+ 'filter_order' => 'CMD',
+ 'filter_order_Dir' => 'CMD',
+ 'lang' => 'CMD',
+ ];
+ // Check for edit form.
+ if ($vName == 'form' && !$this->checkEditId('com_weblinks.edit.weblink', $id)) {
+ // Somehow the person just went to the form - we don't allow that.
+ throw new \Exception(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 403);
+ }
- if ($this->app->getIdentity()->id ||($this->input->getMethod() == 'POST' && $vName == 'categories'))
- {
- $cacheable = false;
- }
-
- $safeurlparams = array(
- 'id' => 'INT',
- 'limit' => 'UINT',
- 'limitstart' => 'UINT',
- 'filter_order' => 'CMD',
- 'filter_order_Dir' => 'CMD',
- 'lang' => 'CMD'
- );
-
- // Check for edit form.
- if ($vName == 'form' && !$this->checkEditId('com_weblinks.edit.weblink', $id))
- {
- // Somehow the person just went to the form - we don't allow that.
- throw new \Exception(Text::sprintf('JLIB_APPLICATION_ERROR_UNHELD_ID', $id), 403);
- }
-
- return parent::display($cacheable, $safeurlparams);
- }
+ return parent::display($cacheable, $safeurlparams);
+ }
}
diff --git a/src/components/com_weblinks/src/Controller/WeblinkController.php b/src/components/com_weblinks/src/Controller/WeblinkController.php
index 85f0d4f..404829a 100644
--- a/src/components/com_weblinks/src/Controller/WeblinkController.php
+++ b/src/components/com_weblinks/src/Controller/WeblinkController.php
@@ -1,4 +1,5 @@
setRedirect($this->getReturnPage());
+ return false;
+ }
- /**
- * The URL view list variable.
- *
- * @var string
- * @since 1.6
- */
- protected $view_list = 'categories';
+ return true;
+ }
- /**
- * The URL edit variable.
- *
- * @var string
- * @since 3.2
- */
- protected $urlVar = 'a.id';
+ /**
+ * 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 = [])
+ {
+ $categoryId = ArrayHelper::getValue($data, 'catid', $this->input->getInt('id'), 'int');
+ if ($categoryId) {
+ // If the category has been passed in the URL check it.
+ return $this->app->getIdentity()->authorise('core.create', $this->option . '.category.' . $categoryId);
+ }
- /**
- * Method to add a new record.
- *
- * @return boolean True if the article can be added, false if not.
- *
- * @since 1.6
- */
- public function add()
- {
- if (!parent::add())
- {
- // Redirect to the return page.
- $this->setRedirect($this->getReturnPage());
+ // In the absence of better information, revert to the component permissions.
+ return parent::allowAdd($data);
+ }
- return false;
- }
+ /**
+ * Method to check if you can add a new 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 = [], $key = 'id')
+ {
+ $recordId = (int) isset($data[$key]) ? $data[$key] : 0;
+ if (!$recordId) {
+ return false;
+ }
- return true;
- }
+ $record = $this->getModel()->getItem($recordId);
+ $categoryId = (int) $record->catid;
+ if ($categoryId) {
+ // The category has been set. Check the category permissions.
+ $user = $this->app->getIdentity();
+ // First, check edit permission
+ if ($user->authorise('core.edit', $this->option . '.category.' . $categoryId)) {
+ return true;
+ }
- /**
- * 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('id'), 'int');
+ // Fallback on edit.own
+ if ($user->authorise('core.edit.own', $this->option . '.category.' . $categoryId) && $record->created_by == $user->id) {
+ return true;
+ }
- if ($categoryId)
- {
- // If the category has been passed in the URL check it.
- return $this->app->getIdentity()->authorise('core.create', $this->option . '.category.' . $categoryId);
- }
+ return false;
+ }
- // In the absence of better information, revert to the component permissions.
- return parent::allowAdd($data);
- }
+ // Since there is no asset tracking, revert to the component permissions.
+ return parent::allowEdit($data, $key);
+ }
- /**
- * Method to check if you can add a new 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;
+ /**
+ * 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 = 'w_id')
+ {
+ $return = parent::cancel($key);
+ // Redirect to the return page.
+ $this->setRedirect($this->getReturnPage());
+ return $return;
+ }
- if (!$recordId)
- {
- return false;
- }
+ /**
+ * 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 = 'w_id')
+ {
+ return parent::edit($key, $urlVar);
+ }
- $record = $this->getModel()->getItem($recordId);
- $categoryId = (int) $record->catid;
+ /**
+ * Method to get a model object, loading it if required.
+ *
+ * @param string $name The model name. Optional.
+ * @param string $prefix The class prefix. Optional.
+ * @param array $config Configuration array for model. Optional.
+ *
+ * @return object The model.
+ *
+ * @since 1.5
+ */
+ public function getModel($name = 'form', $prefix = 'Site', $config = ['ignore_request' => true])
+ {
+ return parent::getModel($name, $prefix, $config);
+ }
- if ($categoryId)
- {
- // The category has been set. Check the category permissions.
- $user = $this->app->getIdentity();
+ /**
+ * 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 = null)
+ {
+ $append = parent::getRedirectToItemAppend($recordId, $urlVar);
+ $itemId = $this->input->getInt('Itemid');
+ $return = $this->getReturnPage();
+ if ($itemId) {
+ $append .= '&Itemid=' . $itemId;
+ }
- // First, check edit permission
- if ($user->authorise('core.edit', $this->option . '.category.' . $categoryId))
- {
- return true;
- }
+ if ($return) {
+ $append .= '&return=' . base64_encode($return);
+ }
- // Fallback on edit.own
- if ($user->authorise('core.edit.own', $this->option . '.category.' . $categoryId) && $record->created_by == $user->id)
- {
- return true;
- }
+ return $append;
+ }
- return false;
- }
+ /**
+ * Get the return URL if a "return" variable has been passed in the request
+ *
+ * @return string The return URL.
+ *
+ * @since 1.6
+ */
+ protected function getReturnPage()
+ {
+ $return = $this->input->get('return', null, 'base64');
+ if (empty($return) || !Uri::isInternal(base64_decode($return))) {
+ return Uri::base();
+ }
- // Since there is no asset tracking, revert to the component permissions.
- return parent::allowEdit($data, $key);
- }
+ return base64_decode($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 = 'w_id')
- {
- $return = parent::cancel($key);
+ /**
+ * 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 = 'w_id')
+ {
+ // Get the application
+ $app = $this->app;
+ // Get the data from POST
+ $data = $this->input->post->get('jform', [], 'array');
+ // Save the data in the session.
+ $app->setUserState('com_weblinks.edit.weblink.data', $data);
+ $result = parent::save($key, $urlVar);
+ // If ok, redirect to the return page.
+ if ($result) {
+ // Flush the data from the session
+ $app->setUserState('com_weblinks.edit.weblink.data', null);
+ $this->setRedirect($this->getReturnPage());
+ }
- // Redirect to the return page.
- $this->setRedirect($this->getReturnPage());
+ return $result;
+ }
- return $return;
- }
+ /**
+ * Go to a weblink
+ *
+ * @return void
+ *
+ * @throws \Exception
+ *
+ * @since 1.6
+ */
+ public function go()
+ {
+ // Get the ID from the request
+ $id = $this->input->getInt('id');
+ // Get the model, requiring published items
+ $modelLink = $this->getModel('Weblink');
+ $modelLink->setState('filter.published', 1);
+ // Get the item
+ $link = $modelLink->getItem($id);
+ // Make sure the item was found.
+ if (empty($link)) {
+ throw new \Exception(Text::_('COM_WEBLINKS_ERROR_WEBLINK_NOT_FOUND'), 404);
+ }
- /**
- * 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 = 'w_id')
- {
- return parent::edit($key, $urlVar);
- }
+ // Check whether item access level allows access.
+ $groups = $this->app->getIdentity()->getAuthorisedViewLevels();
+ if (!in_array($link->access, $groups)) {
+ throw new \Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403);
+ }
- /**
- * Method to get a model object, loading it if required.
- *
- * @param string $name The model name. Optional.
- * @param string $prefix The class prefix. Optional.
- * @param array $config Configuration array for model. Optional.
- *
- * @return object The model.
- *
- * @since 1.5
- */
- public function getModel($name = 'form', $prefix = 'Site', $config = array('ignore_request' => true))
- {
- return parent::getModel($name, $prefix, $config);
- }
+ // Check whether category access level allows access.
+ $modelCat = $this->getModel('Category', 'Site', ['ignore_request' => true]);
+ $modelCat->setState('filter.published', 1);
+ // Get the category
+ $category = $modelCat->getCategory($link->catid);
+ // Make sure the category was found.
+ if (empty($category)) {
+ throw new \Exception(Text::_('COM_WEBLINKS_ERROR_WEBLINK_NOT_FOUND'), 404);
+ }
- /**
- * 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 = null)
- {
- $append = parent::getRedirectToItemAppend($recordId, $urlVar);
- $itemId = $this->input->getInt('Itemid');
- $return = $this->getReturnPage();
+ // Check whether item access level allows access.
+ if (!in_array($category->access, $groups)) {
+ throw new \Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403);
+ }
- if ($itemId)
- {
- $append .= '&Itemid=' . $itemId;
- }
+ // Redirect to the URL
+ if ($link->url) {
+ $modelLink->hit($id);
+ $this->app->redirect($link->url, 301);
+ }
- if ($return)
- {
- $append .= '&return=' . base64_encode($return);
- }
-
- return $append;
- }
-
- /**
- * Get the return URL if a "return" variable has been passed in the request
- *
- * @return string The return URL.
- *
- * @since 1.6
- */
- protected function getReturnPage()
- {
- $return = $this->input->get('return', null, 'base64');
-
- if (empty($return) || !Uri::isInternal(base64_decode($return)))
- {
- return Uri::base();
- }
-
- return base64_decode($return);
- }
-
- /**
- * 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 = 'w_id')
- {
- // Get the application
- $app = $this->app;
-
- // Get the data from POST
- $data = $this->input->post->get('jform', array(), 'array');
-
- // Save the data in the session.
- $app->setUserState('com_weblinks.edit.weblink.data', $data);
- $result = parent::save($key, $urlVar);
-
- // If ok, redirect to the return page.
- if ($result)
- {
- // Flush the data from the session
- $app->setUserState('com_weblinks.edit.weblink.data', null);
- $this->setRedirect($this->getReturnPage());
- }
-
- return $result;
- }
-
- /**
- * Go to a weblink
- *
- * @return void
- *
- * @throws \Exception
- *
- * @since 1.6
- */
- public function go()
- {
- // Get the ID from the request
- $id = $this->input->getInt('id');
-
- // Get the model, requiring published items
- $modelLink = $this->getModel('Weblink');
- $modelLink->setState('filter.published', 1);
-
- // Get the item
- $link = $modelLink->getItem($id);
-
- // Make sure the item was found.
- if (empty($link))
- {
- throw new \Exception(Text::_('COM_WEBLINKS_ERROR_WEBLINK_NOT_FOUND'), 404);
- }
-
- // Check whether item access level allows access.
- $groups = $this->app->getIdentity()->getAuthorisedViewLevels();
-
- if (!in_array($link->access, $groups))
- {
- throw new \Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403);
- }
-
- // Check whether category access level allows access.
- $modelCat = $this->getModel('Category', 'Site', array('ignore_request' => true));
- $modelCat->setState('filter.published', 1);
-
- // Get the category
- $category = $modelCat->getCategory($link->catid);
-
- // Make sure the category was found.
- if (empty($category))
- {
- throw new \Exception(Text::_('COM_WEBLINKS_ERROR_WEBLINK_NOT_FOUND'), 404);
- }
-
- // Check whether item access level allows access.
- if (!in_array($category->access, $groups))
- {
- throw new \Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403);
- }
-
- // Redirect to the URL
- if ($link->url)
- {
- $modelLink->hit($id);
- $this->app->redirect($link->url, 301);
- }
-
- throw new \Exception(Text::_('COM_WEBLINKS_ERROR_WEBLINK_URL_INVALID'), 404);
- }
+ throw new \Exception(Text::_('COM_WEBLINKS_ERROR_WEBLINK_URL_INVALID'), 404);
+ }
}
diff --git a/src/components/com_weblinks/src/Helper/AssociationHelper.php b/src/components/com_weblinks/src/Helper/AssociationHelper.php
index 279bc37..6f73064 100644
--- a/src/components/com_weblinks/src/Helper/AssociationHelper.php
+++ b/src/components/com_weblinks/src/Helper/AssociationHelper.php
@@ -1,4 +1,5 @@
input;
- $view = is_null($view) ? $input->get('view') : $view;
- $id = empty($id) ? $input->getInt('id') : $id;
+ /**
+ * 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 3.0
+ */
+ public static function getAssociations($id = 0, $view = null)
+ {
+ $input = Factory::getApplication()->input;
+ $view = is_null($view) ? $input->get('view') : $view;
+ $id = empty($id) ? $input->getInt('id') : $id;
+ if ($view === 'weblink') {
+ if ($id) {
+ $associations = Associations::getAssociations('com_weblinks', '#__weblinks', 'com_weblinks.item', $id);
+ $return = [];
+ foreach ($associations as $tag => $item) {
+ $return[$tag] = RouteHelper::getWeblinkRoute($item->id, (int) $item->catid, $item->language);
+ }
- if ($view === 'weblink')
- {
- if ($id)
- {
- $associations = Associations::getAssociations('com_weblinks', '#__weblinks', 'com_weblinks.item', $id);
+ return $return;
+ }
+ }
- $return = array();
+ if ($view == 'category' || $view == 'categories') {
+ return self::getCategoryAssociations($id, 'com_weblinks');
+ }
- foreach ($associations as $tag => $item)
- {
- $return[$tag] = RouteHelper::getWeblinkRoute($item->id, (int) $item->catid, $item->language);
- }
-
- return $return;
- }
- }
-
- if ($view == 'category' || $view == 'categories')
- {
- return self::getCategoryAssociations($id, 'com_weblinks');
- }
-
- return array();
- }
+ return [];
+ }
}
diff --git a/src/components/com_weblinks/src/Helper/RouteHelper.php b/src/components/com_weblinks/src/Helper/RouteHelper.php
index c85a2a2..f3b4cfa 100644
--- a/src/components/com_weblinks/src/Helper/RouteHelper.php
+++ b/src/components/com_weblinks/src/Helper/RouteHelper.php
@@ -1,4 +1,5 @@
1) {
+ $link .= '&catid=' . $catid;
+ }
- if ($catid > 1)
- {
- $link .= '&catid=' . $catid;
- }
+ if ($language && $language !== '*' && Multilanguage::isEnabled()) {
+ $link .= '&lang=' . $language;
+ }
- if ($language && $language !== '*' && Multilanguage::isEnabled())
- {
- $link .= '&lang=' . $language;
- }
+ return $link;
+ }
- return $link;
- }
+ /**
+ * Ge the form route
+ *
+ * @param integer $id The id of the weblink.
+ * @param string $return The return page variable.
+ *
+ * @return string
+ */
+ public static function getFormRoute($id, $return = null)
+ {
+ // Create the link.
+ if ($id) {
+ $link = 'index.php?option=com_weblinks&task=weblink.edit&w_id=' . $id;
+ } else {
+ $link = 'index.php?option=com_weblinks&task=weblink.add&w_id=0';
+ }
- /**
- * Ge the form route
- *
- * @param integer $id The id of the weblink.
- * @param string $return The return page variable.
- *
- * @return string
- */
- public static function getFormRoute($id, $return = null)
- {
- // Create the link.
- if ($id)
- {
- $link = 'index.php?option=com_weblinks&task=weblink.edit&w_id=' . $id;
- }
- else
- {
- $link = 'index.php?option=com_weblinks&task=weblink.add&w_id=0';
- }
+ if ($return) {
+ $link .= '&return=' . $return;
+ }
- if ($return)
- {
- $link .= '&return=' . $return;
- }
+ return $link;
+ }
- return $link;
- }
+ /**
+ * Get the Category Route
+ *
+ * @param CategoryNode|string|integer $catid JCategoryNode object or category ID
+ * @param integer $language Language code
+ *
+ * @return string
+ */
+ public static function getCategoryRoute($catid, $language = 0)
+ {
+ if ($catid instanceof CategoryNode) {
+ $id = $catid->id;
+ } else {
+ $id = (int) $catid;
+ }
- /**
- * Get the Category Route
- *
- * @param CategoryNode|string|integer $catid JCategoryNode object or category ID
- * @param integer $language Language code
- *
- * @return string
- */
- public static function getCategoryRoute($catid, $language = 0)
- {
- if ($catid instanceof CategoryNode)
- {
- $id = $catid->id;
- }
- else
- {
- $id = (int) $catid;
- }
+ if ($id < 1) {
+ $link = '';
+ } else {
+ // Create the link
+ $link = 'index.php?option=com_weblinks&view=category&id=' . $id;
+ if ($language && $language !== '*' && Multilanguage::isEnabled()) {
+ $link .= '&lang=' . $language;
+ }
+ }
- if ($id < 1)
- {
- $link = '';
- }
- else
- {
- // Create the link
- $link = 'index.php?option=com_weblinks&view=category&id=' . $id;
-
- if ($language && $language !== '*' && Multilanguage::isEnabled())
- {
- $link .= '&lang=' . $language;
- }
- }
-
- return $link;
- }
+ return $link;
+ }
}
diff --git a/src/components/com_weblinks/src/Model/CategoriesModel.php b/src/components/com_weblinks/src/Model/CategoriesModel.php
index a3cc4bf..4744d68 100644
--- a/src/components/com_weblinks/src/Model/CategoriesModel.php
+++ b/src/components/com_weblinks/src/Model/CategoriesModel.php
@@ -1,4 +1,5 @@
setState('filter.extension', $this->_extension);
+ // Get the parent id if defined.
+ $parentId = $app->input->getInt('id');
+ $this->setState('filter.parentId', $parentId);
+ $params = $app->getParams();
+ $this->setState('params', $params);
+ $this->setState('filter.published', 1);
+ $this->setState('filter.access', true);
+ }
- /**
- * The category context (allows other extensions to derived from this model).
- *
- * @var string
- */
- protected $_extension = 'com_weblinks';
+ /**
+ * 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.extension');
+ $id .= ':' . $this->getState('filter.published');
+ $id .= ':' . $this->getState('filter.access');
+ $id .= ':' . $this->getState('filter.parentId');
+ return parent::getStoreId($id);
+ }
- /**
- * Parent category
- *
- * @var CategoryNode|null
- */
- private $_parent = null;
+ /**
+ * Redefine the function and add some properties to make the styling more easy
+ *
+ * @return mixed An array of data items on success, false on failure.
+ */
+ public function getItems()
+ {
+ if ($this->_items === null) {
+ $params = $this->getState('params', new Registry());
+ $options = [];
+ $options['access'] = $this->getState('filter.access');
+ $options['published'] = $this->getState('filter.published');
+ $options['countItems'] = $params->get('show_cat_num_links', 1) || !$params->get('show_empty_categories_cat', 0);
+ $categories = Categories::getInstance('Weblinks', $options);
+ $this->_parent = $categories->get($this->getState('filter.parentId', 'root'));
+ if (is_object($this->_parent)) {
+ $this->_items = $this->_parent->getChildren();
+ } else {
+ $this->_items = false;
+ }
+ }
- /**
- * Categories data
- *
- * @var false|array
- */
- private $_items = null;
+ return $this->_items;
+ }
- /**
- * 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 = null, $direction = null)
- {
- $app = Factory::getApplication();
- $this->setState('filter.extension', $this->_extension);
+ /**
+ * Get the parent
+ *
+ * @return mixed An array of data items on success, false on failure.
+ */
+ public function getParent()
+ {
+ if (!is_object($this->_parent)) {
+ $this->getItems();
+ }
- // Get the parent id if defined.
- $parentId = $app->input->getInt('id');
- $this->setState('filter.parentId', $parentId);
-
- $params = $app->getParams();
- $this->setState('params', $params);
-
- $this->setState('filter.published', 1);
- $this->setState('filter.access', true);
- }
-
- /**
- * 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.extension');
- $id .= ':' . $this->getState('filter.published');
- $id .= ':' . $this->getState('filter.access');
- $id .= ':' . $this->getState('filter.parentId');
-
- return parent::getStoreId($id);
- }
-
- /**
- * Redefine the function and add some properties to make the styling more easy
- *
- * @return mixed An array of data items on success, false on failure.
- */
- public function getItems()
- {
- if ($this->_items === null)
- {
- $params = $this->getState('params', new Registry);
-
- $options = array();
- $options['access'] = $this->getState('filter.access');
- $options['published'] = $this->getState('filter.published');
- $options['countItems'] = $params->get('show_cat_num_links', 1) || !$params->get('show_empty_categories_cat', 0);
- $categories = Categories::getInstance('Weblinks', $options);
- $this->_parent = $categories->get($this->getState('filter.parentId', 'root'));
-
- if (is_object($this->_parent))
- {
- $this->_items = $this->_parent->getChildren();
- }
- else
- {
- $this->_items = false;
- }
- }
-
- return $this->_items;
- }
-
- /**
- * Get the parent
- *
- * @return mixed An array of data items on success, false on failure.
- */
- public function getParent()
- {
- if (!is_object($this->_parent))
- {
- $this->getItems();
- }
-
- return $this->_parent;
- }
+ return $this->_parent;
+ }
}
diff --git a/src/components/com_weblinks/src/Model/CategoryModel.php b/src/components/com_weblinks/src/Model/CategoryModel.php
index 47a2a7d..c17a6e4 100644
--- a/src/components/com_weblinks/src/Model/CategoryModel.php
+++ b/src/components/com_weblinks/src/Model/CategoryModel.php
@@ -1,4 +1,5 @@
_params))
- {
- $item->params = new Registry($item->params);
- }
-
- // Some contexts may not use tags data at all, so we allow callers to disable loading tag data
- if ($this->getState('load_tags', true))
- {
- $item->tags = new TagsHelper;
- $taggedItems[$item->id] = $item;
- }
- }
-
- // Load tags of all items.
- if ($taggedItems)
- {
- $tagsHelper = new TagsHelper();
- $itemIds = \array_keys($taggedItems);
-
- foreach ($tagsHelper->getMultipleItemTags('com_weblinks.weblink', $itemIds) as $id => $tags)
- {
- $taggedItems[$id]->tags->itemTags = $tags;
- }
- }
-
- return $items;
- }
-
- /**
- * 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 1.6
- */
- protected function getListQuery()
- {
- $viewLevels = $this->getCurrentUser()->getAuthorisedViewLevels();
-
- // Create a new query object.
- $db = $this->getDatabase();
- $query = $db->getQuery(true);
-
- // Select required fields from the categories.
- $query->select($this->getState('list.select', 'a.*'))
- ->from($db->quoteName('#__weblinks') . ' AS a')
- ->whereIn($db->quoteName('a.access'), $viewLevels);
-
- // Filter by category.
- if ($categoryId = $this->getState('category.id'))
- {
- // Group by subcategory
- if ($this->getState('category.group', 0))
- {
- $query->select('c.title AS category_title')
- ->where('c.parent_id = :parent_id')
- ->bind(':parent_id', $categoryId, ParameterType::INTEGER)
- ->join('LEFT', '#__categories AS c ON c.id = a.catid')
- ->whereIn($db->quoteName('c.access'), $viewLevels);
- }
- else
- {
- $query->where('a.catid = :catid')
- ->bind(':catid', $categoryId, ParameterType::INTEGER)
- ->join('LEFT', '#__categories AS c ON c.id = a.catid')
- ->whereIn($db->quoteName('c.access'), $viewLevels);
- }
-
- // Filter by published category
- $cpublished = $this->getState('filter.c.published');
-
- if (is_numeric($cpublished))
- {
- $query->where('c.published = :published')
- ->bind(':published', $cpublished, ParameterType::INTEGER);
- }
- }
-
- // Join over the users for the author and modified_by names.
- $query->select("CASE WHEN a.created_by_alias > ' ' THEN a.created_by_alias ELSE ua.name END AS author")
- ->select("ua.email AS author_email")
- ->join('LEFT', '#__users AS ua ON ua.id = a.created_by')
- ->join('LEFT', '#__users AS uam ON uam.id = a.modified_by');
-
- // Filter by state
- $state = $this->getState('filter.state');
-
- if (is_numeric($state))
- {
- $query->where('a.state = :state')
- ->bind(':state', $state, ParameterType::INTEGER);
- }
-
- // Do not show trashed links on the front-end
- $query->where('a.state != -2');
-
- // Filter by start and end dates.
- if ($this->getState('filter.publish_date'))
- {
- $nowDate = Factory::getDate()->toSql();
- $query->where('(' . $db->quoteName('a.publish_up')
- . ' IS NULL OR ' . $db->quoteName('a.publish_up') . ' <= :publish_up)'
- )
- ->where('(' . $db->quoteName('a.publish_down')
- . ' IS NULL OR ' . $db->quoteName('a.publish_down') . ' >= :publish_down)'
- )
- ->bind(':publish_up', $nowDate)
- ->bind(':publish_down', $nowDate);
- }
-
- // Filter by language
- if ($this->getState('filter.language'))
- {
- $query->whereIn($db->quoteName('a.language'), [Factory::getLanguage()->getTag(), '*'], ParameterType::STRING);
- }
-
- // Filter by search in title
- $search = $this->getState('list.filter');
-
- if (!empty($search))
- {
- $search = '%' . trim($search) . '%';
- $query->where('(a.title LIKE :search)')
- ->bind(':search', $search);
- }
-
- // If grouping by subcategory, add the subcategory list ordering clause.
- if ($this->getState('category.group', 0))
- {
- $query->order(
- $db->escape($this->getState('category.ordering', 'c.lft')) . ' ' .
- $db->escape($this->getState('category.direction', 'ASC'))
- );
- }
-
- // 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 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 = null, $direction = null)
- {
- $app = Factory::getApplication();
-
- $params = $app->getParams();
- $this->setState('params', $params);
-
- // List state information
- $limit = $app->getUserStateFromRequest('global.list.limit', 'limit', $app->get('list_limit'), 'uint');
- $this->setState('list.limit', $limit);
-
- $limitstart = $app->input->get('limitstart', 0, 'uint');
- $this->setState('list.start', $limitstart);
-
- // Optional filter text
- $this->setState('list.filter', $app->input->getString('filter-search'));
-
- $orderCol = $app->input->get('filter_order', 'ordering');
-
- if (!in_array($orderCol, $this->filter_fields))
- {
- $orderCol = 'ordering';
- }
-
- $this->setState('list.ordering', $orderCol);
-
- $listOrder = $app->input->get('filter_order_Dir', 'ASC');
-
- if (!in_array(strtoupper($listOrder), array('ASC', 'DESC', '')))
- {
- $listOrder = 'ASC';
- }
-
- $this->setState('list.direction', $listOrder);
-
- $id = $app->input->get('id', 0, 'int');
- $this->setState('category.id', $id);
-
- $user = $this->getCurrentUser();
-
- if (!$user->authorise('core.edit.state', 'com_weblinks') && !$user->authorise('core.edit', 'com_weblinks'))
- {
- // Limit to published for people who can't edit or edit.state.
- $this->setState('filter.state', 1);
-
- // Filter by start and end dates.
- $this->setState('filter.publish_date', true);
- }
-
- $this->setState('filter.language', Multilanguage::isEnabled());
- }
-
- /**
- * Method to get category data for the current category
- *
- * @return object
- *
- * @since 1.5
- */
- public function getCategory()
- {
- if (!is_object($this->_item))
- {
- $params = $this->getState('params', new Registry);
-
- $options = array();
- $options['countItems'] = $params->get('show_cat_num_links_cat', 1)
- || $params->get('show_empty_categories', 0);
-
- $categories = Categories::getInstance('Weblinks', $options);
- $this->_item = $categories->get($this->getState('category.id', 'root'));
-
- if (is_object($this->_item))
- {
- $this->_children = $this->_item->getChildren();
- $this->_parent = false;
-
- if ($this->_item->getParent())
- {
- $this->_parent = $this->_item->getParent();
- }
-
- $this->_rightsibling = $this->_item->getSibling();
- $this->_leftsibling = $this->_item->getSibling(false);
- }
- else
- {
- $this->_children = false;
- $this->_parent = false;
- }
- }
-
- return $this->_item;
- }
-
- /**
- * Get the parent category
- *
- * @return mixed An array of categories or false if an error occurs.
- */
- public function getParent()
- {
- if (!is_object($this->_item))
- {
- $this->getCategory();
- }
-
- return $this->_parent;
- }
-
- /**
- * Get the leftsibling (adjacent) categories.
- *
- * @return mixed An array of categories or false if an error occurs.
- */
- public function &getLeftSibling()
- {
- if (!is_object($this->_item))
- {
- $this->getCategory();
- }
-
- return $this->_leftsibling;
- }
-
- /**
- * Get the rightsibling (adjacent) categories.
- *
- * @return mixed An array of categories or false if an error occurs.
- */
- public function &getRightSibling()
- {
- if (!is_object($this->_item))
- {
- $this->getCategory();
- }
-
- return $this->_rightsibling;
- }
-
- /**
- * Get the child categories.
- *
- * @return mixed An array of categories or false if an error occurs.
- */
- public function &getChildren()
- {
- if (!is_object($this->_item))
- {
- $this->getCategory();
- }
-
- return $this->_children;
- }
-
- /**
- * Increment the hit counter for the category.
- *
- * @param integer $pk Optional primary key of the category to increment.
- *
- * @return boolean True if successful; false otherwise and internal error set.
- *
- * @since 3.2
- */
- public function hit($pk = 0)
- {
- $hitcount = Factory::getApplication()->input->getInt('hitcount', 1);
-
- if ($hitcount)
- {
- $pk = (!empty($pk)) ? $pk : (int) $this->getState('category.id');
- $table = Table::getInstance('Category', 'Joomla\\CMS\\Table\\');
- $table->load($pk);
- $table->hit($pk);
- }
-
- return true;
- }
+ /**
+ * Category item data
+ *
+ * @var CategoryNode|null
+ */
+ protected $_item = null;
+
+ /**
+ * Category left of this one
+ *
+ * @var CategoryNode|null
+ */
+ protected $_leftsibling = null;
+
+ /**
+ * Category right right of this one
+ *
+ * @var CategoryNode|null
+ */
+ protected $_rightsibling = null;
+
+ /**
+ * Array of child-categories
+ *
+ * @var CategoryNode[]|null
+ */
+ protected $_children = null;
+
+ /**
+ * Parent category of the current one
+ *
+ * @var CategoryNode|null
+ */
+ protected $_parent = null;
+
+ /**
+ * Constructor.
+ *
+ * @param array $config An optional associative array of configuration settings.
+ *
+ * @see JControllerLegacy
+ * @since 1.6
+ */
+ public function __construct($config = [])
+ {
+ if (empty($config['filter_fields'])) {
+ $config['filter_fields'] = [
+ 'id', 'a.id',
+ 'title', 'a.title',
+ 'hits', 'a.hits',
+ 'ordering', 'a.ordering',
+ ];
+ }
+
+ parent::__construct($config);
+ }
+
+
+ /**
+ * Method to get a list of items.
+ *
+ * @return mixed An array of objects on success, false on failure.
+ */
+ public function getItems()
+ {
+ // Invoke the parent getItems method to get the main list
+ $items = parent::getItems();
+
+ $taggedItems = [];
+
+ // Convert the params field into an object, saving original in _params
+ foreach ($items as $item) {
+ if (!isset($this->_params)) {
+ $item->params = new Registry($item->params);
+ }
+
+ // Some contexts may not use tags data at all, so we allow callers to disable loading tag data
+ if ($this->getState('load_tags', true)) {
+ $item->tags = new TagsHelper();
+ $taggedItems[$item->id] = $item;
+ }
+ }
+
+ // Load tags of all items.
+ if ($taggedItems) {
+ $tagsHelper = new TagsHelper();
+ $itemIds = \array_keys($taggedItems);
+
+ foreach ($tagsHelper->getMultipleItemTags('com_weblinks.weblink', $itemIds) as $id => $tags) {
+ $taggedItems[$id]->tags->itemTags = $tags;
+ }
+ }
+
+ return $items;
+ }
+
+ /**
+ * 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 1.6
+ */
+ protected function getListQuery()
+ {
+ $viewLevels = $this->getCurrentUser()->getAuthorisedViewLevels();
+
+ // Create a new query object.
+ $db = $this->getDatabase();
+ $query = $db->getQuery(true);
+
+ // Select required fields from the categories.
+ $query->select($this->getState('list.select', 'a.*'))
+ ->from($db->quoteName('#__weblinks') . ' AS a')
+ ->whereIn($db->quoteName('a.access'), $viewLevels);
+
+ // Filter by category.
+ if ($categoryId = $this->getState('category.id')) {
+ // Group by subcategory
+ if ($this->getState('category.group', 0)) {
+ $query->select('c.title AS category_title')
+ ->where('c.parent_id = :parent_id')
+ ->bind(':parent_id', $categoryId, ParameterType::INTEGER)
+ ->join('LEFT', '#__categories AS c ON c.id = a.catid')
+ ->whereIn($db->quoteName('c.access'), $viewLevels);
+ } else {
+ $query->where('a.catid = :catid')
+ ->bind(':catid', $categoryId, ParameterType::INTEGER)
+ ->join('LEFT', '#__categories AS c ON c.id = a.catid')
+ ->whereIn($db->quoteName('c.access'), $viewLevels);
+ }
+
+ // Filter by published category
+ $cpublished = $this->getState('filter.c.published');
+
+ if (is_numeric($cpublished)) {
+ $query->where('c.published = :published')
+ ->bind(':published', $cpublished, ParameterType::INTEGER);
+ }
+ }
+
+ // Join over the users for the author and modified_by names.
+ $query->select("CASE WHEN a.created_by_alias > ' ' THEN a.created_by_alias ELSE ua.name END AS author")
+ ->select("ua.email AS author_email")
+ ->join('LEFT', '#__users AS ua ON ua.id = a.created_by')
+ ->join('LEFT', '#__users AS uam ON uam.id = a.modified_by');
+
+ // Filter by state
+ $state = $this->getState('filter.state');
+
+ if (is_numeric($state)) {
+ $query->where('a.state = :state')
+ ->bind(':state', $state, ParameterType::INTEGER);
+ }
+
+ // Do not show trashed links on the front-end
+ $query->where('a.state != -2');
+
+ // Filter by start and end dates.
+ if ($this->getState('filter.publish_date')) {
+ $nowDate = Factory::getDate()->toSql();
+ $query->where('(' . $db->quoteName('a.publish_up')
+ . ' IS NULL OR ' . $db->quoteName('a.publish_up') . ' <= :publish_up)')
+ ->where('(' . $db->quoteName('a.publish_down')
+ . ' IS NULL OR ' . $db->quoteName('a.publish_down') . ' >= :publish_down)')
+ ->bind(':publish_up', $nowDate)
+ ->bind(':publish_down', $nowDate);
+ }
+
+ // Filter by language
+ if ($this->getState('filter.language')) {
+ $query->whereIn($db->quoteName('a.language'), [Factory::getLanguage()->getTag(), '*'], ParameterType::STRING);
+ }
+
+ // Filter by search in title
+ $search = $this->getState('list.filter');
+
+ if (!empty($search)) {
+ $search = '%' . trim($search) . '%';
+ $query->where('(a.title LIKE :search)')
+ ->bind(':search', $search);
+ }
+
+ // If grouping by subcategory, add the subcategory list ordering clause.
+ if ($this->getState('category.group', 0)) {
+ $query->order(
+ $db->escape($this->getState('category.ordering', 'c.lft')) . ' ' .
+ $db->escape($this->getState('category.direction', 'ASC'))
+ );
+ }
+
+ // 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 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 = null, $direction = null)
+ {
+ $app = Factory::getApplication();
+
+ $params = $app->getParams();
+ $this->setState('params', $params);
+
+ // List state information
+ $limit = $app->getUserStateFromRequest('global.list.limit', 'limit', $app->get('list_limit'), 'uint');
+ $this->setState('list.limit', $limit);
+
+ $limitstart = $app->input->get('limitstart', 0, 'uint');
+ $this->setState('list.start', $limitstart);
+
+ // Optional filter text
+ $this->setState('list.filter', $app->input->getString('filter-search'));
+
+ $orderCol = $app->input->get('filter_order', 'ordering');
+
+ if (!in_array($orderCol, $this->filter_fields)) {
+ $orderCol = 'ordering';
+ }
+
+ $this->setState('list.ordering', $orderCol);
+
+ $listOrder = $app->input->get('filter_order_Dir', 'ASC');
+
+ if (!in_array(strtoupper($listOrder), ['ASC', 'DESC', ''])) {
+ $listOrder = 'ASC';
+ }
+
+ $this->setState('list.direction', $listOrder);
+
+ $id = $app->input->get('id', 0, 'int');
+ $this->setState('category.id', $id);
+
+ $user = $this->getCurrentUser();
+
+ if (!$user->authorise('core.edit.state', 'com_weblinks') && !$user->authorise('core.edit', 'com_weblinks')) {
+ // Limit to published for people who can't edit or edit.state.
+ $this->setState('filter.state', 1);
+
+ // Filter by start and end dates.
+ $this->setState('filter.publish_date', true);
+ }
+
+ $this->setState('filter.language', Multilanguage::isEnabled());
+ }
+
+ /**
+ * Method to get category data for the current category
+ *
+ * @return object
+ *
+ * @since 1.5
+ */
+ public function getCategory()
+ {
+ if (!is_object($this->_item)) {
+ $params = $this->getState('params', new Registry());
+
+ $options = [];
+ $options['countItems'] = $params->get('show_cat_num_links_cat', 1)
+ || $params->get('show_empty_categories', 0);
+
+ $categories = Categories::getInstance('Weblinks', $options);
+ $this->_item = $categories->get($this->getState('category.id', 'root'));
+
+ if (is_object($this->_item)) {
+ $this->_children = $this->_item->getChildren();
+ $this->_parent = false;
+
+ if ($this->_item->getParent()) {
+ $this->_parent = $this->_item->getParent();
+ }
+
+ $this->_rightsibling = $this->_item->getSibling();
+ $this->_leftsibling = $this->_item->getSibling(false);
+ } else {
+ $this->_children = false;
+ $this->_parent = false;
+ }
+ }
+
+ return $this->_item;
+ }
+
+ /**
+ * Get the parent category
+ *
+ * @return mixed An array of categories or false if an error occurs.
+ */
+ public function getParent()
+ {
+ if (!is_object($this->_item)) {
+ $this->getCategory();
+ }
+
+ return $this->_parent;
+ }
+
+ /**
+ * Get the leftsibling (adjacent) categories.
+ *
+ * @return mixed An array of categories or false if an error occurs.
+ */
+ public function &getLeftSibling()
+ {
+ if (!is_object($this->_item)) {
+ $this->getCategory();
+ }
+
+ return $this->_leftsibling;
+ }
+
+ /**
+ * Get the rightsibling (adjacent) categories.
+ *
+ * @return mixed An array of categories or false if an error occurs.
+ */
+ public function &getRightSibling()
+ {
+ if (!is_object($this->_item)) {
+ $this->getCategory();
+ }
+
+ return $this->_rightsibling;
+ }
+
+ /**
+ * Get the child categories.
+ *
+ * @return mixed An array of categories or false if an error occurs.
+ */
+ public function &getChildren()
+ {
+ if (!is_object($this->_item)) {
+ $this->getCategory();
+ }
+
+ return $this->_children;
+ }
+
+ /**
+ * Increment the hit counter for the category.
+ *
+ * @param integer $pk Optional primary key of the category to increment.
+ *
+ * @return boolean True if successful; false otherwise and internal error set.
+ *
+ * @since 3.2
+ */
+ public function hit($pk = 0)
+ {
+ $hitcount = Factory::getApplication()->input->getInt('hitcount', 1);
+
+ if ($hitcount) {
+ $pk = (!empty($pk)) ? $pk : (int) $this->getState('category.id');
+ $table = Table::getInstance('Category', 'Joomla\\CMS\\Table\\');
+ $table->load($pk);
+ $table->hit($pk);
+ }
+
+ return true;
+ }
}
diff --git a/src/components/com_weblinks/src/Model/FormModel.php b/src/components/com_weblinks/src/Model/FormModel.php
index 6de943e..c8e1778 100644
--- a/src/components/com_weblinks/src/Model/FormModel.php
+++ b/src/components/com_weblinks/src/Model/FormModel.php
@@ -1,4 +1,5 @@
getState('return_page', ''));
- }
+ /**
+ * Get the return URL.
+ *
+ * @return string The return URL.
+ *
+ * @since 1.6
+ */
+ public function getReturnPage()
+ {
+ return base64_encode($this->getState('return_page', ''));
+ }
- /**
- * 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();
+ /**
+ * 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 state from the request.
- $pk = $app->input->getInt('w_id');
- $this->setState('weblink.id', $pk);
+ // Load state from the request.
+ $pk = $app->input->getInt('w_id');
+ $this->setState('weblink.id', $pk);
- // Add compatibility variable for default naming conventions.
- $this->setState('form.id', $pk);
+ // Add compatibility variable for default naming conventions.
+ $this->setState('form.id', $pk);
- $categoryId = $app->input->getInt('catid');
- $this->setState('weblink.catid', $categoryId);
+ $categoryId = $app->input->getInt('catid');
+ $this->setState('weblink.catid', $categoryId);
- $return = $app->input->get('return', '', 'base64');
+ $return = $app->input->get('return', '', 'base64');
- if ($return && !Uri::isInternal(base64_decode($return)))
- {
- $return = '';
- }
+ if ($return && !Uri::isInternal(base64_decode($return))) {
+ $return = '';
+ }
- $this->setState('return_page', base64_decode($return));
+ $this->setState('return_page', base64_decode($return));
- // Load the parameters.
- $params = $app->getParams();
- $this->setState('params', $params);
+ // Load the parameters.
+ $params = $app->getParams();
+ $this->setState('params', $params);
- $this->setState('layout', $app->input->getString('layout'));
- }
+ $this->setState('layout', $app->input->getString('layout'));
+ }
- /**
- * 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 __DEPLOY_VERSION__
- */
- public function getForm($data = array(), $loadData = true)
- {
- $form = $this->loadForm('com_weblinks.form', 'weblink', array('control' => 'jform', 'load_data' => $loadData));
+ /**
+ * 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 __DEPLOY_VERSION__
+ */
+ public function getForm($data = [], $loadData = true)
+ {
+ $form = $this->loadForm('com_weblinks.form', 'weblink', ['control' => 'jform', 'load_data' => $loadData]);
- // Disable the buttons and just allow editor none for not authenticated users
- if ($this->getCurrentUser()->guest)
- {
- $form->setFieldAttribute('description', 'editor', 'none');
- $form->setFieldAttribute('description', 'buttons', 'no');
- }
+ // Disable the buttons and just allow editor none for not authenticated users
+ if ($this->getCurrentUser()->guest) {
+ $form->setFieldAttribute('description', 'editor', 'none');
+ $form->setFieldAttribute('description', 'buttons', 'no');
+ }
- return $form;
- }
+ return $form;
+ }
- /**
- * Method to get a table object, load it if necessary.
- *
- * @param string $name The table name. Optional.
- * @param string $prefix The class prefix. Optional.
- * @param array $options Configuration array for model. Optional.
- *
- * @return Table A Table object
- *
- * @since 4.0.0
- * @throws \Exception
- */
- public function getTable($name = 'Weblink', $prefix = 'Administrator', $options = array())
- {
- return parent::getTable($name, $prefix, $options);
- }
+ /**
+ * 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 Table object
+ *
+ * @since 4.0.0
+ * @throws \Exception
+ */
+ public function getTable($name = 'Weblink', $prefix = 'Administrator', $options = [])
+ {
+ return parent::getTable($name, $prefix, $options);
+ }
}
diff --git a/src/components/com_weblinks/src/Model/WeblinkModel.php b/src/components/com_weblinks/src/Model/WeblinkModel.php
index 959cb5d..82a0733 100644
--- a/src/components/com_weblinks/src/Model/WeblinkModel.php
+++ b/src/components/com_weblinks/src/Model/WeblinkModel.php
@@ -1,4 +1,5 @@
input->getInt('id');
- $this->setState('weblink.id', $pk);
+ // Load the object state.
+ $pk = $app->input->getInt('id');
+ $this->setState('weblink.id', $pk);
- // Load the parameters.
- $params = $app->getParams();
- $this->setState('params', $params);
+ // Load the parameters.
+ $params = $app->getParams();
+ $this->setState('params', $params);
- $user = $this->getCurrentUser();
+ $user = $this->getCurrentUser();
- if (!$user->authorise('core.edit.state', 'com_weblinks') && !$user->authorise('core.edit', 'com_weblinks'))
- {
- $this->setState('filter.published', 1);
- $this->setState('filter.archived', 2);
- }
+ if (!$user->authorise('core.edit.state', 'com_weblinks') && !$user->authorise('core.edit', 'com_weblinks')) {
+ $this->setState('filter.published', 1);
+ $this->setState('filter.archived', 2);
+ }
- $this->setState('filter.language', Multilanguage::isEnabled());
- }
+ $this->setState('filter.language', Multilanguage::isEnabled());
+ }
- /**
- * Method to get an object.
- *
- * @param integer $pk The id of the object to get.
- *
- * @return mixed Object on success, false on failure.
- */
- public function getItem($pk = null)
- {
- $user = $this->getCurrentUser();
+ /**
+ * Method to get an object.
+ *
+ * @param integer $pk The id of the object to get.
+ *
+ * @return mixed Object on success, false on failure.
+ */
+ public function getItem($pk = null)
+ {
+ $user = $this->getCurrentUser();
- $pk = (!empty($pk)) ? $pk : (int) $this->getState('weblink.id');
+ $pk = (!empty($pk)) ? $pk : (int) $this->getState('weblink.id');
- if ($this->_item === null)
- {
- $this->_item = array();
- }
+ if ($this->_item === null) {
+ $this->_item = [];
+ }
- if (!isset($this->_item[$pk]))
- {
- try
- {
- $db = $this->getDatabase();
- $query = $db->getQuery(true)
- ->select($this->getState('item.select', 'a.*'))
- ->from('#__weblinks AS a')
- ->where($db->quoteName('a.id') . ' = :id')
- ->bind(':id', $pk, ParameterType::INTEGER);
+ if (!isset($this->_item[$pk])) {
+ try {
+ $db = $this->getDatabase();
+ $query = $db->getQuery(true)
+ ->select($this->getState('item.select', 'a.*'))
+ ->from('#__weblinks AS a')
+ ->where($db->quoteName('a.id') . ' = :id')
+ ->bind(':id', $pk, ParameterType::INTEGER);
- // Join on category table.
- $query->select('c.title AS category_title, c.alias AS category_alias, c.access AS category_access')
- ->innerJoin('#__categories AS c on c.id = a.catid')
- ->where('c.published > 0');
+ // Join on category table.
+ $query->select('c.title AS category_title, c.alias AS category_alias, c.access AS category_access')
+ ->innerJoin('#__categories AS c on c.id = a.catid')
+ ->where('c.published > 0');
- // Join on user table.
- $query->select('u.name AS author')
- ->join('LEFT', '#__users AS u on u.id = a.created_by');
+ // Join on user table.
+ $query->select('u.name AS author')
+ ->join('LEFT', '#__users AS u on u.id = a.created_by');
- // Filter by language
- if ($this->getState('filter.language'))
- {
- $query->whereIn($db->quoteName('a.language'), [Factory::getLanguage()->getTag(), '*'], ParameterType::STRING);
- }
+ // Filter by language
+ if ($this->getState('filter.language')) {
+ $query->whereIn($db->quoteName('a.language'), [Factory::getLanguage()->getTag(), '*'], ParameterType::STRING);
+ }
- // Join over the categories to get parent category titles
- $query->select('parent.title as parent_title, parent.id as parent_id, parent.path as parent_route, parent.alias as parent_alias')
- ->join('LEFT', '#__categories as parent ON parent.id = c.parent_id');
+ // Join over the categories to get parent category titles
+ $query->select('parent.title as parent_title, parent.id as parent_id, parent.path as parent_route, parent.alias as parent_alias')
+ ->join('LEFT', '#__categories as parent ON parent.id = c.parent_id');
- if (!$user->authorise('core.edit.state', 'com_weblinks') && !$user->authorise('core.edit', 'com_weblinks'))
- {
- // Filter by start and end dates.
- $nowDate = Factory::getDate()->toSql();
- $query->where('(' . $db->quoteName('a.publish_up')
- . ' IS NULL OR ' . $db->quoteName('a.publish_up') . ' <= :publish_up)'
- )
- ->where('(' . $db->quoteName('a.publish_down')
- . ' IS NULL OR ' . $db->quoteName('a.publish_down') . ' >= :publish_down)'
- )
- ->bind(':publish_up', $nowDate)
- ->bind(':publish_down', $nowDate);
- }
+ if (!$user->authorise('core.edit.state', 'com_weblinks') && !$user->authorise('core.edit', 'com_weblinks')) {
+ // Filter by start and end dates.
+ $nowDate = Factory::getDate()->toSql();
+ $query->where('(' . $db->quoteName('a.publish_up')
+ . ' IS NULL OR ' . $db->quoteName('a.publish_up') . ' <= :publish_up)')
+ ->where('(' . $db->quoteName('a.publish_down')
+ . ' IS NULL OR ' . $db->quoteName('a.publish_down') . ' >= :publish_down)')
+ ->bind(':publish_up', $nowDate)
+ ->bind(':publish_down', $nowDate);
+ }
- // Filter by published state.
- $published = $this->getState('filter.published');
- $archived = $this->getState('filter.archived');
+ // Filter by published state.
+ $published = $this->getState('filter.published');
+ $archived = $this->getState('filter.archived');
- if (is_numeric($published))
- {
- $query->whereIn($db->quoteName('a.state'), [$published, $archived]);
- }
+ if (is_numeric($published)) {
+ $query->whereIn($db->quoteName('a.state'), [$published, $archived]);
+ }
- $db->setQuery($query);
+ $db->setQuery($query);
- $data = $db->loadObject();
+ $data = $db->loadObject();
- if (empty($data))
- {
- throw new \Exception(Text::_('COM_WEBLINKS_ERROR_WEBLINK_NOT_FOUND'), 404);
- }
+ if (empty($data)) {
+ throw new \Exception(Text::_('COM_WEBLINKS_ERROR_WEBLINK_NOT_FOUND'), 404);
+ }
- // Check for published state if filter set.
- if ((is_numeric($published) || is_numeric($archived)) && (($data->state != $published) && ($data->state != $archived)))
- {
- throw new \Exception(Text::_('COM_WEBLINKS_ERROR_WEBLINK_NOT_FOUND'), 404);
- }
+ // Check for published state if filter set.
+ if ((is_numeric($published) || is_numeric($archived)) && (($data->state != $published) && ($data->state != $archived))) {
+ throw new \Exception(Text::_('COM_WEBLINKS_ERROR_WEBLINK_NOT_FOUND'), 404);
+ }
- // Convert parameter fields to objects.
- $data->params = new Registry($data->params);
- $data->metadata = new Registry($data->metadata);
+ // Convert parameter fields to objects.
+ $data->params = new Registry($data->params);
+ $data->metadata = new Registry($data->metadata);
- // Some contexts may not use tags data at all, so we allow callers to disable loading tag data
- if ($this->getState('load_tags', true))
- {
- $data->tags = new TagsHelper;
- $data->tags->getItemTags('com_weblinks.weblink', $data->id);
- }
+ // Some contexts may not use tags data at all, so we allow callers to disable loading tag data
+ if ($this->getState('load_tags', true)) {
+ $data->tags = new TagsHelper();
+ $data->tags->getItemTags('com_weblinks.weblink', $data->id);
+ }
- // Compute access permissions.
- if ($access = $this->getState('filter.access'))
- {
- // If the access filter has been set, we already know this user can view.
- $data->params->set('access-view', true);
- }
- else
- {
- // If no access filter is set, the layout takes some responsibility for display of limited information.
- $groups = $user->getAuthorisedViewLevels();
- $data->params->set('access-view', in_array($data->access, $groups) && in_array($data->category_access, $groups));
- }
+ // Compute access permissions.
+ if ($access = $this->getState('filter.access')) {
+ // If the access filter has been set, we already know this user can view.
+ $data->params->set('access-view', true);
+ } else {
+ // If no access filter is set, the layout takes some responsibility for display of limited information.
+ $groups = $user->getAuthorisedViewLevels();
+ $data->params->set('access-view', in_array($data->access, $groups) && in_array($data->category_access, $groups));
+ }
- $this->_item[$pk] = $data;
- }
- catch (\Exception $e)
- {
- $this->setError($e);
- $this->_item[$pk] = false;
- }
- }
+ $this->_item[$pk] = $data;
+ } catch (\Exception $e) {
+ $this->setError($e);
+ $this->_item[$pk] = false;
+ }
+ }
- return $this->_item[$pk];
- }
+ return $this->_item[$pk];
+ }
- /**
- * 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 = 'Weblink', $prefix = 'Administrator', $config = array())
- {
- return parent::getTable($type, $prefix, $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 Table A database object
+ *
+ * @since 1.6
+ */
+ public function getTable($type = 'Weblink', $prefix = 'Administrator', $config = [])
+ {
+ return parent::getTable($type, $prefix, $config);
+ }
- /**
- * Method to increment the hit counter for the weblink
- *
- * @param integer $pk Optional ID of the weblink.
- *
- * @return boolean True on success
- */
- public function hit($pk = null)
- {
- if (empty($pk))
- {
- $pk = $this->getState('weblink.id');
- }
+ /**
+ * Method to increment the hit counter for the weblink
+ *
+ * @param integer $pk Optional ID of the weblink.
+ *
+ * @return boolean True on success
+ */
+ public function hit($pk = null)
+ {
+ if (empty($pk)) {
+ $pk = $this->getState('weblink.id');
+ }
- return $this->getTable('Weblink')->hit($pk);
- }
+ return $this->getTable('Weblink')->hit($pk);
+ }
}
diff --git a/src/components/com_weblinks/src/Service/Category.php b/src/components/com_weblinks/src/Service/Category.php
index 1c8f1c3..ba82752 100644
--- a/src/components/com_weblinks/src/Service/Category.php
+++ b/src/components/com_weblinks/src/Service/Category.php
@@ -1,4 +1,5 @@
categoryFactory = $categoryFactory;
+ $this->db = $db;
+ $params = ComponentHelper::getParams('com_weblinks');
+ $this->noIDs = (bool) $params->get('sef_ids');
+ $categories = new RouterViewConfiguration('categories');
+ $categories->setKey('id');
+ $this->registerView($categories);
+ $category = new RouterViewConfiguration('category');
+ $category->setKey('id')->setParent($categories, 'catid')->setNestable();
+ $this->registerView($category);
+ $webLink = new RouterViewConfiguration('weblink');
+ $webLink->setKey('id')->setParent($category, 'catid');
+ $this->registerView($webLink);
+ $form = new RouterViewConfiguration('form');
+ $form->setKey('w_id');
+ $this->registerView($form);
+ parent::__construct($app, $menu);
+ $this->attachRule(new MenuRules($this));
+ $this->attachRule(new StandardRules($this));
+ $this->attachRule(new NomenuRules($this));
+ }
- /**
- * The category factory
- *
- * @var CategoryFactoryInterface
- *
- * @since 4.0.0
- */
- private $categoryFactory;
+ /**
+ * Method to get the segment(s) for a category
+ *
+ * @param string $id ID of the category to retrieve the segments for
+ * @param array $query The request that is built right now
+ *
+ * @return array|string The segments of this item
+ */
+ public function getCategorySegment($id, $query)
+ {
+ $category = $this->getCategories()->get($id);
+ if ($category) {
+ $path = array_reverse($category->getPath(), true);
+ $path[0] = '1:root';
+ if ($this->noIDs) {
+ foreach ($path as &$segment) {
+ list($id, $segment) = explode(':', $segment, 2);
+ }
+ }
- /**
- * The category cache
- *
- * @var array
- *
- * @since 4.0.0
- */
- private $categoryCache = [];
+ return $path;
+ }
- /**
- * The db
- *
- * @var DatabaseInterface
- *
- * @since 4.0.0
- */
- private $db;
+ return [];
+ }
- /**
- * Weblinks Component router constructor
- *
- * @param SiteApplication $app The application object
- * @param AbstractMenu $menu The menu object to work with
- * @param CategoryFactoryInterface $categoryFactory The category object
- * @param DatabaseInterface $db The database object
- */
- public function __construct(SiteApplication $app, AbstractMenu $menu, CategoryFactoryInterface $categoryFactory, DatabaseInterface $db)
- {
- $this->categoryFactory = $categoryFactory;
- $this->db = $db;
+ /**
+ * Method to get the segment(s) for a category
+ *
+ * @param string $id ID of the category to retrieve the segments for
+ * @param array $query The request that is built right now
+ *
+ * @return array|string The segments of this item
+ */
+ public function getCategoriesSegment($id, $query)
+ {
+ return $this->getCategorySegment($id, $query);
+ }
- $params = ComponentHelper::getParams('com_weblinks');
- $this->noIDs = (bool) $params->get('sef_ids');
- $categories = new RouterViewConfiguration('categories');
- $categories->setKey('id');
- $this->registerView($categories);
- $category = new RouterViewConfiguration('category');
- $category->setKey('id')->setParent($categories, 'catid')->setNestable();
- $this->registerView($category);
- $webLink = new RouterViewConfiguration('weblink');
- $webLink->setKey('id')->setParent($category, 'catid');
- $this->registerView($webLink);
- $form = new RouterViewConfiguration('form');
- $form->setKey('w_id');
- $this->registerView($form);
+ /**
+ * Method to get the segment(s) for a weblink
+ *
+ * @param string $id ID of the weblink to retrieve the segments for
+ * @param array $query The request that is built right now
+ *
+ * @return array|string The segments of this item
+ */
+ public function getWeblinkSegment($id, $query)
+ {
+ if (!strpos($id, ':')) {
+ $id = (int) $id;
+ $dbquery = $this->db->getQuery(true);
+ $dbquery->select($this->db->quoteName('alias'))
+ ->from($this->db->quoteName('#__weblinks'))
+ ->where($this->db->quoteName('id') . ' = :id')
+ ->bind(':id', $id, ParameterType::INTEGER);
+ $this->db->setQuery($dbquery);
+ $id .= ':' . $this->db->loadResult();
+ }
- parent::__construct($app, $menu);
+ if ($this->noIDs) {
+ list($void, $segment) = explode(':', $id, 2);
+ return [$void => $segment];
+ }
- $this->attachRule(new MenuRules($this));
- $this->attachRule(new StandardRules($this));
- $this->attachRule(new NomenuRules($this));
- }
+ return [(int) $id => $id];
+ }
- /**
- * Method to get the segment(s) for a category
- *
- * @param string $id ID of the category to retrieve the segments for
- * @param array $query The request that is built right now
- *
- * @return array|string The segments of this item
- */
- public function getCategorySegment($id, $query)
- {
- $category = $this->getCategories()->get($id);
+ /**
+ * Method to get the segment(s) for a form
+ *
+ * @param string $id ID of the weblink form to retrieve the segments for
+ * @param array $query The request that is built right now
+ *
+ * @return array|string The segments of this item
+ *
+ * @since 4.0.0
+ */
+ public function getFormSegment($id, $query)
+ {
+ return $this->getWeblinkSegment($id, $query);
+ }
- if ($category)
- {
- $path = array_reverse($category->getPath(), true);
- $path[0] = '1:root';
+ /**
+ * Method to get the id for a category
+ *
+ * @param string $segment Segment to retrieve the ID for
+ * @param array $query The request that is parsed right now
+ *
+ * @return mixed The id of this item or false
+ */
+ public function getCategoryId($segment, $query)
+ {
+ if (isset($query['id'])) {
+ $category = $this->getCategories(['access' => false])->get($query['id']);
+ if ($category) {
+ foreach ($category->getChildren() as $child) {
+ if ($this->noIDs) {
+ if ($child->alias == $segment) {
+ return $child->id;
+ }
+ } else {
+ if ($child->id == (int) $segment) {
+ return $child->id;
+ }
+ }
+ }
+ }
+ }
- if ($this->noIDs)
- {
- foreach ($path as &$segment)
- {
- list($id, $segment) = explode(':', $segment, 2);
- }
- }
+ return false;
+ }
- return $path;
- }
+ /**
+ * Method to get the segment(s) for a category
+ *
+ * @param string $segment Segment to retrieve the ID for
+ * @param array $query The request that is parsed right now
+ *
+ * @return mixed The id of this item or false
+ */
+ public function getCategoriesId($segment, $query)
+ {
+ return $this->getCategoryId($segment, $query);
+ }
- return array();
- }
+ /**
+ * Method to get the segment(s) for a weblink
+ *
+ * @param string $segment Segment of the weblink to retrieve the ID for
+ * @param array $query The request that is parsed right now
+ *
+ * @return mixed The id of this item or false
+ */
+ public function getWeblinkId($segment, $query)
+ {
+ if ($this->noIDs) {
+ $dbquery = $this->db->getQuery(true);
+ $dbquery->select($this->db->quoteName('id'))
+ ->from($this->db->quoteName('#__weblinks'))
+ ->where([
+ $this->db->quoteName('alias') . ' = :alias',
+ $this->db->quoteName('catid') . ' = :catid',
+ ])
+ ->bind(':alias', $segment)
+ ->bind(':catid', $query['id'], ParameterType::INTEGER);
+ $this->db->setQuery($dbquery);
+ return (int) $this->db->loadResult();
+ }
- /**
- * Method to get the segment(s) for a category
- *
- * @param string $id ID of the category to retrieve the segments for
- * @param array $query The request that is built right now
- *
- * @return array|string The segments of this item
- */
- public function getCategoriesSegment($id, $query)
- {
- return $this->getCategorySegment($id, $query);
- }
+ return (int) $segment;
+ }
- /**
- * Method to get the segment(s) for a weblink
- *
- * @param string $id ID of the weblink to retrieve the segments for
- * @param array $query The request that is built right now
- *
- * @return array|string The segments of this item
- */
- public function getWeblinkSegment($id, $query)
- {
- if (!strpos($id, ':'))
- {
- $id = (int) $id;
- $dbquery = $this->db->getQuery(true);
- $dbquery->select($this->db->quoteName('alias'))
- ->from($this->db->quoteName('#__weblinks'))
- ->where($this->db->quoteName('id') . ' = :id')
- ->bind(':id', $id, ParameterType::INTEGER);
- $this->db->setQuery($dbquery);
+ /**
+ * Method to get categories from cache
+ *
+ * @param array $options The options for retrieving categories
+ *
+ * @return CategoryInterface The object containing categories
+ *
+ * @since 4.0.0
+ */
+ private function getCategories(array $options = []): CategoryInterface
+ {
+ $key = serialize($options);
+ if (!isset($this->categoryCache[$key])) {
+ $this->categoryCache[$key] = $this->categoryFactory->createCategory($options);
+ }
- $id .= ':' . $this->db->loadResult();
- }
-
- if ($this->noIDs)
- {
- list($void, $segment) = explode(':', $id, 2);
-
- return array($void => $segment);
- }
-
- return array((int) $id => $id);
- }
-
- /**
- * Method to get the segment(s) for a form
- *
- * @param string $id ID of the weblink form to retrieve the segments for
- * @param array $query The request that is built right now
- *
- * @return array|string The segments of this item
- *
- * @since 4.0.0
- */
- public function getFormSegment($id, $query)
- {
- return $this->getWeblinkSegment($id, $query);
- }
-
- /**
- * Method to get the id for a category
- *
- * @param string $segment Segment to retrieve the ID for
- * @param array $query The request that is parsed right now
- *
- * @return mixed The id of this item or false
- */
- public function getCategoryId($segment, $query)
- {
- if (isset($query['id']))
- {
- $category = $this->getCategories(['access' => false])->get($query['id']);
-
- if ($category)
- {
- foreach ($category->getChildren() as $child)
- {
- if ($this->noIDs)
- {
- if ($child->alias == $segment)
- {
- return $child->id;
- }
- }
- else
- {
- if ($child->id == (int) $segment)
- {
- return $child->id;
- }
- }
- }
- }
- }
-
- return false;
- }
-
- /**
- * Method to get the segment(s) for a category
- *
- * @param string $segment Segment to retrieve the ID for
- * @param array $query The request that is parsed right now
- *
- * @return mixed The id of this item or false
- */
- public function getCategoriesId($segment, $query)
- {
- return $this->getCategoryId($segment, $query);
- }
-
- /**
- * Method to get the segment(s) for a weblink
- *
- * @param string $segment Segment of the weblink to retrieve the ID for
- * @param array $query The request that is parsed right now
- *
- * @return mixed The id of this item or false
- */
- public function getWeblinkId($segment, $query)
- {
- if ($this->noIDs)
- {
- $dbquery = $this->db->getQuery(true);
- $dbquery->select($this->db->quoteName('id'))
- ->from($this->db->quoteName('#__weblinks'))
- ->where(
- [
- $this->db->quoteName('alias') . ' = :alias',
- $this->db->quoteName('catid') . ' = :catid',
- ]
- )
- ->bind(':alias', $segment)
- ->bind(':catid', $query['id'], ParameterType::INTEGER);
- $this->db->setQuery($dbquery);
-
- return (int) $this->db->loadResult();
- }
-
- return (int) $segment;
- }
-
- /**
- * Method to get categories from cache
- *
- * @param array $options The options for retrieving categories
- *
- * @return CategoryInterface The object containing categories
- *
- * @since 4.0.0
- */
- private function getCategories(array $options = []): CategoryInterface
- {
- $key = serialize($options);
-
- if (!isset($this->categoryCache[$key]))
- {
- $this->categoryCache[$key] = $this->categoryFactory->createCategory($options);
- }
-
- return $this->categoryCache[$key];
- }
+ return $this->categoryCache[$key];
+ }
}
diff --git a/src/components/com_weblinks/src/View/Categories/HtmlView.php b/src/components/com_weblinks/src/View/Categories/HtmlView.php
index 8e30794..0e1e0dc 100644
--- a/src/components/com_weblinks/src/View/Categories/HtmlView.php
+++ b/src/components/com_weblinks/src/View/Categories/HtmlView.php
@@ -1,4 +1,5 @@
items as $item) {
+ $item->slug = $item->alias ? ($item->id . ':' . $item->alias) : $item->id;
+ $temp = $item->params;
+ $item->params = clone $this->params;
+ $item->params->merge($temp);
+ if ($item->params->get('count_clicks', 1) == 1) {
+ $item->link = Route::_('index.php?option=com_weblinks&task=weblink.go&id=' . $item->id);
+ } else {
+ $item->link = $item->url;
+ }
+ }
- /**
- * Execute and display a template script.
- *
- * @param string $tpl The name of the template file to parse; automatically searches through the template paths.
- *
- * @return mixed A string if successful, otherwise a Error object.
- */
- public function display($tpl = null)
- {
- parent::commonCategoryDisplay();
+ return parent::display($tpl);
+ }
- // Prepare the data.
- // Compute the weblink slug & link url.
- foreach ($this->items as $item)
- {
- $item->slug = $item->alias ? ($item->id . ':' . $item->alias) : $item->id;
- $temp = $item->params;
- $item->params = clone $this->params;
- $item->params->merge($temp);
+ /**
+ * Prepares the document
+ *
+ * @return void
+ */
+ protected function prepareDocument()
+ {
+ parent::prepareDocument();
+ parent::addFeed();
+ if ($this->menuItemMatchCategory) {
+ // If the active menu item is linked directly to the category being displayed, no further process is needed
+ return;
+ }
- if ($item->params->get('count_clicks', 1) == 1)
- {
- $item->link = Route::_('index.php?option=com_weblinks&task=weblink.go&id=' . $item->id);
- }
- else
- {
- $item->link = $item->url;
- }
- }
+ // Get ID of the category from active menu item
+ $menu = $this->menu;
- return parent::display($tpl);
- }
+ if (
+ $menu && $menu->component == 'com_weblinks' && isset($menu->query['view'])
+ && in_array($menu->query['view'], ['categories', 'category'])
+ ) {
+ $id = $menu->query['id'];
+ } else {
+ $id = 0;
+ }
- /**
- * Prepares the document
- *
- * @return void
- */
- protected function prepareDocument()
- {
- parent::prepareDocument();
+ $path = [['title' => $this->category->title, 'link' => '']];
+ $category = $this->category->getParent();
+ while ($category !== null && $category->id != $id && $category->id !== 'root') {
+ $path[] = ['title' => $category->title, 'link' => RouteHelper::getCategoryRoute($category->id, $category->language)];
+ $category = $category->getParent();
+ }
- parent::addFeed();
-
- if ($this->menuItemMatchCategory)
- {
- // If the active menu item is linked directly to the category being displayed, no further process is needed
- return;
- }
-
- // Get ID of the category from active menu item
- $menu = $this->menu;
-
- if ($menu && $menu->component == 'com_weblinks' && isset($menu->query['view'])
- && in_array($menu->query['view'], ['categories', 'category']))
- {
- $id = $menu->query['id'];
- }
- else
- {
- $id = 0;
- }
-
- $path = [['title' => $this->category->title, 'link' => '']];
- $category = $this->category->getParent();
-
- while ($category !== null && $category->id != $id && $category->id !== 'root')
- {
- $path[] = ['title' => $category->title, 'link' => RouteHelper::getCategoryRoute($category->id, $category->language)];
- $category = $category->getParent();
- }
-
- $path = array_reverse($path);
-
- foreach ($path as $item)
- {
- $this->pathway->addItem($item['title'], $item['link']);
- }
- }
+ $path = array_reverse($path);
+ foreach ($path as $item) {
+ $this->pathway->addItem($item['title'], $item['link']);
+ }
+ }
}
diff --git a/src/components/com_weblinks/src/View/Form/HtmlView.php b/src/components/com_weblinks/src/View/Form/HtmlView.php
index 00348d1..dfa26f7 100644
--- a/src/components/com_weblinks/src/View/Form/HtmlView.php
+++ b/src/components/com_weblinks/src/View/Form/HtmlView.php
@@ -1,4 +1,5 @@
getCurrentUser();
+ /**
+ * Display the view.
+ *
+ * @param string $tpl The name of the template file to parse; automatically searches through the template paths.
+ *
+ * @return mixed A string if successful, otherwise an Error object.
+ */
+ public function display($tpl = null)
+ {
+ $user = $this->getCurrentUser();
- // Get model data.
- $this->state = $this->get('State');
- $this->item = $this->get('Item');
- $this->form = $this->get('Form');
- $this->return_page = $this->get('ReturnPage');
+ // Get model data.
+ $this->state = $this->get('State');
+ $this->item = $this->get('Item');
+ $this->form = $this->get('Form');
+ $this->return_page = $this->get('ReturnPage');
- if (empty($this->item->id))
- {
- $authorised = $user->authorise('core.create', 'com_weblinks') || count($user->getAuthorisedCategories('com_weblinks', 'core.create'));
- }
- else
- {
- $authorised = $user->authorise('core.edit', 'com_weblinks.category.' . $this->item->catid);
- }
+ if (empty($this->item->id)) {
+ $authorised = $user->authorise('core.create', 'com_weblinks') || count($user->getAuthorisedCategories('com_weblinks', 'core.create'));
+ } else {
+ $authorised = $user->authorise('core.edit', 'com_weblinks.category.' . $this->item->catid);
+ }
- if ($authorised !== true)
- {
- throw new \Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403);
- }
+ if ($authorised !== true) {
+ throw new \Exception(Text::_('JERROR_ALERTNOAUTHOR'), 403);
+ }
- if (!empty($this->item))
- {
- // Override the base weblink data with any data in the session.
- $temp = (array) Factory::getApplication()->getUserState('com_weblinks.edit.weblink.data', array());
+ if (!empty($this->item)) {
+ // Override the base weblink data with any data in the session.
+ $temp = (array) Factory::getApplication()->getUserState('com_weblinks.edit.weblink.data', []);
- foreach ($temp as $k => $v)
- {
- $this->item->$k = $v;
- }
+ foreach ($temp as $k => $v) {
+ $this->item->$k = $v;
+ }
- $this->form->bind($this->item);
- }
+ $this->form->bind($this->item);
+ }
- // Check for errors.
- if (count($errors = $this->get('Errors')))
- {
- throw new GenericDataException(implode("\n", $errors), 500);
- }
+ // Check for errors.
+ if (count($errors = $this->get('Errors'))) {
+ throw new GenericDataException(implode("\n", $errors), 500);
+ }
- // Create a shortcut to the parameters.
- $params = &$this->state->params;
+ // Create a shortcut to the parameters.
+ $params = &$this->state->params;
- // Escape strings for HTML output
- $this->pageclass_sfx = htmlspecialchars($params->get('pageclass_sfx', ''));
+ // Escape strings for HTML output
+ $this->pageclass_sfx = htmlspecialchars($params->get('pageclass_sfx', ''));
- $this->params = $params;
- $this->user = $user;
+ $this->params = $params;
+ $this->user = $user;
- $this->_prepareDocument();
+ $this->prepareDocument();
- parent::display($tpl);
- }
+ parent::display($tpl);
+ }
- /**
- * Prepares the document
- *
- * @return void
- */
- protected function _prepareDocument()
- {
- $app = Factory::getApplication();
+ /**
+ * Prepares the document
+ *
+ * @return void
+ */
+ protected function prepareDocument()
+ {
+ $app = Factory::getApplication();
- // Because the application sets a default page title,
- // we need to get it from the menu item itself
- $menu = $app->getMenu()->getActive();
+ // Because the application sets a default page title,
+ // we need to get it from the menu item itself
+ $menu = $app->getMenu()->getActive();
- if (empty($this->item->id))
- {
- $head = Text::_('COM_WEBLINKS_FORM_SUBMIT_WEBLINK');
- }
- else
- {
- $head = Text::_('COM_WEBLINKS_FORM_EDIT_WEBLINK');
- }
+ if (empty($this->item->id)) {
+ $head = Text::_('COM_WEBLINKS_FORM_SUBMIT_WEBLINK');
+ } else {
+ $head = Text::_('COM_WEBLINKS_FORM_EDIT_WEBLINK');
+ }
- if ($menu)
- {
- $this->params->def('page_heading', $this->params->get('page_title', $menu->title));
- }
- else
- {
- $this->params->def('page_heading', $head);
- }
+ if ($menu) {
+ $this->params->def('page_heading', $this->params->get('page_title', $menu->title));
+ } else {
+ $this->params->def('page_heading', $head);
+ }
- $title = $this->params->def('page_title', $head);
+ $title = $this->params->def('page_title', $head);
- $this->setDocumentTitle($title);
+ $this->setDocumentTitle($title);
- if ($this->params->get('menu-meta_description'))
- {
- $this->document->setDescription($this->params->get('menu-meta_description'));
- }
+ if ($this->params->get('menu-meta_description')) {
+ $this->document->setDescription($this->params->get('menu-meta_description'));
+ }
- if ($this->params->get('menu-meta_keywords'))
- {
- $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords'));
- }
+ if ($this->params->get('menu-meta_keywords')) {
+ $this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords'));
+ }
- if ($this->params->get('robots'))
- {
- $this->document->setMetadata('robots', $this->params->get('robots'));
- }
- }
+ if ($this->params->get('robots')) {
+ $this->document->setMetadata('robots', $this->params->get('robots'));
+ }
+ }
}
diff --git a/src/components/com_weblinks/src/View/Weblink/HtmlView.php b/src/components/com_weblinks/src/View/Weblink/HtmlView.php
index 3a05ff3..c69e295 100644
--- a/src/components/com_weblinks/src/View/Weblink/HtmlView.php
+++ b/src/components/com_weblinks/src/View/Weblink/HtmlView.php
@@ -1,4 +1,5 @@
item = $this->get('Item');
- $this->state = $this->get('State');
- $this->params = $this->state->get('params');
-
- // Create a shortcut for $item.
- $item = $this->item;
-
- $item->slug = $item->alias ? ($item->id . ':' . $item->alias) : $item->id;
-
- $temp = $item->params;
- $item->params = clone $app->getParams();
- $item->params->merge($temp);
-
- $offset = $this->state->get('list.offset');
-
- $app->triggerEvent('onContentPrepare', array('com_weblinks.weblink', &$item, &$item->params, $offset));
-
- $item->event = new \stdClass;
-
- $results = $app->triggerEvent('onContentAfterTitle', array('com_weblinks.weblink', &$item, &$item->params, $offset));
- $item->event->afterDisplayTitle = trim(implode("\n", $results));
-
- $results = $app->triggerEvent('onContentBeforeDisplay', array('com_weblinks.weblink', &$item, &$item->params, $offset));
- $item->event->beforeDisplayContent = trim(implode("\n", $results));
-
- $results = $app->triggerEvent('onContentAfterDisplay', array('com_weblinks.weblink', &$item, &$item->params, $offset));
- $item->event->afterDisplayContent = trim(implode("\n", $results));
-
- parent::display($tpl);
- }
+ /**
+ * The weblink object
+ *
+ * @var \JObject
+ */
+ protected $item;
+ /**
+ * The page parameters
+ *
+ * @var \Joomla\Registry\Registry|null
+ */
+ protected $params;
+ /**
+ * The item model state
+ *
+ * @var \Joomla\Registry\Registry
+ * @since 1.6
+ */
+ protected $state;
+ /**
+ * Execute and display a template script.
+ *
+ * @param string $tpl The name of the template file to parse; automatically searches through the template paths.
+ *
+ * @return mixed A string if successful, otherwise an Error object.
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function display($tpl = null)
+ {
+ $app = Factory::getApplication();
+ $this->item = $this->get('Item');
+ $this->state = $this->get('State');
+ $this->params = $this->state->get('params');
+ // Create a shortcut for $item.
+ $item = $this->item;
+ $item->slug = $item->alias ? ($item->id . ':' . $item->alias) : $item->id;
+ $temp = $item->params;
+ $item->params = clone $app->getParams();
+ $item->params->merge($temp);
+ $offset = $this->state->get('list.offset');
+ $app->triggerEvent('onContentPrepare', ['com_weblinks.weblink', &$item, &$item->params, $offset]);
+ $item->event = new \stdClass();
+ $results = $app->triggerEvent('onContentAfterTitle', ['com_weblinks.weblink', &$item, &$item->params, $offset]);
+ $item->event->afterDisplayTitle = trim(implode("\n", $results));
+ $results = $app->triggerEvent('onContentBeforeDisplay', ['com_weblinks.weblink', &$item, &$item->params, $offset]);
+ $item->event->beforeDisplayContent = trim(implode("\n", $results));
+ $results = $app->triggerEvent('onContentAfterDisplay', ['com_weblinks.weblink', &$item, &$item->params, $offset]);
+ $item->event->afterDisplayContent = trim(implode("\n", $results));
+ parent::display($tpl);
+ }
}
diff --git a/src/components/com_weblinks/tmpl/categories/default.php b/src/components/com_weblinks/tmpl/categories/default.php
index c7b77a1..2dc2f62 100644
--- a/src/components/com_weblinks/tmpl/categories/default.php
+++ b/src/components/com_weblinks/tmpl/categories/default.php
@@ -1,4 +1,5 @@
document->getWebAssetManager();
$wa->getRegistry()->addExtensionRegistryFile('com_categories');
@@ -23,8 +23,8 @@ $wa->usePreset('com_categories.shared-categories-accordion');
?>
- loadTemplate('items');
- ?>
+ loadTemplate('items');
+ ?>
diff --git a/src/components/com_weblinks/tmpl/categories/default_items.php b/src/components/com_weblinks/tmpl/categories/default_items.php
index 200094d..22d52e9 100644
--- a/src/components/com_weblinks/tmpl/categories/default_items.php
+++ b/src/components/com_weblinks/tmpl/categories/default_items.php
@@ -1,4 +1,5 @@
maxLevelcat != 0 && count($this->items[$this->parent->id]) > 0) :
-?>
-
- items[$this->parent->id] as $id => $item) : ?>
- params->get('show_empty_categories_cat') || $item->numitems || count($item->getChildren())) : ?>
-
-
-
- escape($item->title); ?>
- params->get('show_cat_num_links_cat') == 1) :?>
-
-
- numitems; ?>
-
-
- maxLevelcat > 1 && count($item->getChildren()) > 0) : ?>
-
-
-
-
-
+ ?>
+
+ items[$this->parent->id] as $id => $item) :
+ ?>
+ params->get('show_empty_categories_cat') || $item->numitems || count($item->getChildren())) :
+ ?>
+
+
+
+ escape($item->title); ?>
+ params->get('show_cat_num_links_cat') == 1) :
+ ?>
+
+
+ numitems; ?>
+
+
+ maxLevelcat > 1 && count($item->getChildren()) > 0) :
+ ?>
+
+
+
+
+
- params->get('show_subcat_desc_cat') == 1 && !empty($item->description)) : ?>
-
- description, '', 'com_weblinks.categories'); ?>
-
-
+ params->get('show_subcat_desc_cat') == 1 && !empty($item->description)) :
+ ?>
+
+ description, '', 'com_weblinks.categories'); ?>
+
+
- params->get('show_description_image') && !empty($item->getParams()->get('image'))) : ?>
- getParams();
- $img = HTMLHelper::cleanImageURL($params->get('image'));
- $alt = '';
- if (!empty($params->get('image_alt'))) :
- $alt = 'alt="' . htmlspecialchars($params->get('image_alt'), ENT_COMPAT, 'UTF-8') . '"';
- elseif (!empty($params->get('image_alt_empty'))) :
- $alt = 'alt=""';
- endif;
- ?>
-
>
-
+ params->get('show_description_image') && !empty($item->getParams()->get('image'))) :
+ ?>
+ getParams();
+ $img = HTMLHelper::cleanImageURL($params->get('image'));
+ $alt = '';
+ if (!empty($params->get('image_alt'))) :
+ $alt = 'alt="' . htmlspecialchars($params->get('image_alt'), ENT_COMPAT, 'UTF-8') . '"';
+ elseif (!empty($params->get('image_alt_empty'))) :
+ $alt = 'alt=""';
+ endif;
+ ?>
+
>
+
- maxLevelcat > 1 && count($item->getChildren()) > 0) : ?>
-
- items[$item->id] = $item->getChildren();
- $this->parent = $item;
- $this->maxLevelcat--;
- echo $this->loadTemplate('items');
- $this->parent = $item->getParent();
- $this->maxLevelcat++;
- ?>
-
-
-
-
-
-
-
+ maxLevelcat > 1 && count($item->getChildren()) > 0) :
+ ?>
+
+ items[$item->id] = $item->getChildren();
+ $this->parent = $item;
+ $this->maxLevelcat--;
+ echo $this->loadTemplate('items');
+ $this->parent = $item->getParent();
+ $this->maxLevelcat++;
+ ?>
+
+
+
+
+
+
+
diff --git a/src/components/com_weblinks/tmpl/category/default.php b/src/components/com_weblinks/tmpl/category/default.php
index a5990da..3cc3746 100644
--- a/src/components/com_weblinks/tmpl/category/default.php
+++ b/src/components/com_weblinks/tmpl/category/default.php
@@ -1,4 +1,5 @@
- subtemplatename = 'items';
- echo LayoutHelper::render('joomla.content.category_default', $this);
- ?>
-
\ No newline at end of file
+ subtemplatename = 'items';
+ echo LayoutHelper::render('joomla.content.category_default', $this);
+ ?>
+
diff --git a/src/components/com_weblinks/tmpl/category/default_children.php b/src/components/com_weblinks/tmpl/category/default_children.php
index b128610..cfde6a1 100644
--- a/src/components/com_weblinks/tmpl/category/default_children.php
+++ b/src/components/com_weblinks/tmpl/category/default_children.php
@@ -1,4 +1,5 @@
maxLevel != 0 && count($this->children[$this->category->id]) > 0) :
-?>
-
-
+ getChildren()) > 0) :
+ $this->children[$child->id] = $child->getChildren();
+ $this->category = $child;
+ $this->maxLevel--;
+ echo $this->loadTemplate('children');
+ $this->category = $child->getParent();
+ $this->maxLevel++;
+ endif; ?>
+
+
+
+
+
diff --git a/src/components/com_weblinks/tmpl/category/default_items.php b/src/components/com_weblinks/tmpl/category/default_items.php
index 685dbba..38458d8 100644
--- a/src/components/com_weblinks/tmpl/category/default_items.php
+++ b/src/components/com_weblinks/tmpl/category/default_items.php
@@ -1,4 +1,5 @@
getIdentity();
-
// Check if user is allowed to add/edit based on weblinks permission.
$canEdit = $user->authorise('core.edit', 'com_weblinks.category.' . $this->category->id);
$canEditOwn = $user->authorise('core.edit.own', 'com_weblinks.category.' . $this->category->id);
$canCreate = $user->authorise('core.create', 'com_weblinks.category.' . $this->category->id);
-
$listOrder = $this->escape($this->state->get('list.ordering'));
$listDirn = $this->escape($this->state->get('list.direction'));
?>
diff --git a/src/components/com_weblinks/tmpl/form/edit.php b/src/components/com_weblinks/tmpl/form/edit.php
index 5170723..02fbb63 100644
--- a/src/components/com_weblinks/tmpl/form/edit.php
+++ b/src/components/com_weblinks/tmpl/form/edit.php
@@ -1,4 +1,5 @@
params->get('captcha', Factory::getApplication()->get('captcha', '0'));
-
-foreach (PluginHelper::getPlugin('captcha') as $plugin)
-{
- if ($captchaSet === $plugin->name)
- {
- $captchaEnabled = true;
- break;
- }
+foreach (PluginHelper::getPlugin('captcha') as $plugin) {
+ if ($captchaSet === $plugin->name) {
+ $captchaEnabled = true;
+ break;
+ }
}
// Create shortcut to parameters.
$params = $this->state->get('params');
?>
- params->get('show_page_heading')) : ?>
-
-
-
+ params->get('show_page_heading')) :
+ ?>
+
+
+
- form->renderField('title'); ?>
- form->renderField('alias'); ?>
- form->renderField('catid'); ?>
- form->renderField('url'); ?>
- form->renderField('tags'); ?>
+ form->renderField('title'); ?>
+ form->renderField('alias'); ?>
+ form->renderField('catid'); ?>
+ form->renderField('url'); ?>
+ form->renderField('tags'); ?>
- get('save_history', 0)) : ?>
- form->renderField('version_note'); ?>
-
+ get('save_history', 0)) :
+ ?>
+ form->renderField('version_note'); ?>
+
- user->authorise('core.edit.state', 'com_weblinks.weblink')) : ?>
- form->renderField('state'); ?>
-
- form->renderField('language'); ?>
- form->renderField('description'); ?>
+ user->authorise('core.edit.state', 'com_weblinks.weblink')) :
+ ?>
+ form->renderField('state'); ?>
+
+ form->renderField('language'); ?>
+ form->renderField('description'); ?>
- form->renderField('image_first', 'images'); ?>
- form->renderField('image_first_alt', 'images'); ?>
- form->renderField('image_first_alt_empty', 'images'); ?>
- form->renderField('float_first', 'images'); ?>
- form->renderField('image_first_caption', 'images'); ?>
+ form->renderField('image_first', 'images'); ?>
+ form->renderField('image_first_alt', 'images'); ?>
+ form->renderField('image_first_alt_empty', 'images'); ?>
+ form->renderField('float_first', 'images'); ?>
+ form->renderField('image_first_caption', 'images'); ?>
- form->renderField('image_second', 'images'); ?>
- form->renderField('image_second_alt', 'images'); ?>
- form->renderField('image_second_alt_empty', 'images'); ?>
- form->renderField('float_second', 'images'); ?>
- form->renderField('image_second_caption', 'images'); ?>
+ form->renderField('image_second', 'images'); ?>
+ form->renderField('image_second_alt', 'images'); ?>
+ form->renderField('image_second_alt_empty', 'images'); ?>
+ form->renderField('float_second', 'images'); ?>
+ form->renderField('image_second_caption', 'images'); ?>
-
-
- form->renderField('captcha'); ?>
-
-
+
+
+ form->renderField('captcha'); ?>
+
+
-
-
-
-
-
-
-
-
-
- params->get('save_history', 0) && $this->item->id) : ?>
- form->getInput('contenthistory'); ?>
-
-
+
+
+
+
+
+
+
+
+
+ params->get('save_history', 0) && $this->item->id) :
+ ?>
+ form->getInput('contenthistory'); ?>
+
+
-
-
-
-
+
+
+
+
diff --git a/src/components/com_weblinks/tmpl/weblink/default.php b/src/components/com_weblinks/tmpl/weblink/default.php
index ca40dc6..46eb7b9 100644
--- a/src/components/com_weblinks/tmpl/weblink/default.php
+++ b/src/components/com_weblinks/tmpl/weblink/default.php
@@ -1,4 +1,5 @@
item->url);
$user = Factory::getApplication()->getIdentity();
-
$canEdit = $user->authorise('core.edit', 'com_weblinks.category.' . $this->item->catid);
-
-if (!$canEdit)
-{
- $canEditOwn = $user->authorise('core.edit.own', 'com_weblinks.category.' . $this->item->catid);
- $canEdit = $canEditOwn && $this->item->created_by == $user->id;
+if (!$canEdit) {
+ $canEditOwn = $user->authorise('core.edit.own', 'com_weblinks.category.' . $this->item->catid);
+ $canEdit = $canEditOwn && $this->item->created_by == $user->id;
}
?>
-
-
-
-
-
-
- item, $this->item->params); ?>
-
-
-
-
+
+
+
+
+
+
+ item, $this->item->params); ?>
+
+
+
+
-
- item->event->afterDisplayTitle; ?>
+
+ item->event->afterDisplayTitle; ?>
-
- item->event->beforeDisplayContent; ?>
+
+ item->event->beforeDisplayContent; ?>
-
-
+
+
- params->get('show_tags', 1) && !empty($this->item->tags->itemTags)) : ?>
-
- item->tags->itemTags); ?>
-
-
+ params->get('show_tags', 1) && !empty($this->item->tags->itemTags)) :
+ ?>
+
+ item->tags->itemTags); ?>
+
+
-
- item->images); ?>
- image_first)) : ?>
-
- float_first)) : ?>
- float_first == 'right' ? 'float-end' : 'float-start'; ?>
-
- image_first); ?>
- image_first_alt) && empty($images->image_first_alt_empty)
- ? ''
- : 'alt="' . htmlspecialchars($images->image_first_alt, ENT_COMPAT, 'UTF-8') . '"'; ?>
-
- itemprop="thumbnail" />
- image_first_caption)) : ?>
- image_first_caption, ENT_COMPAT, 'UTF-8'); ?>
-
-
-
+
+ item->images); ?>
+ image_first)) :
+ ?>
+
+ float_first)) :
+ ?>
+ float_first == 'right' ? 'float-end' : 'float-start'; ?>
+
+ image_first); ?>
+ image_first_alt) && empty($images->image_first_alt_empty)
+ ? ''
+ : 'alt="' . htmlspecialchars($images->image_first_alt, ENT_COMPAT, 'UTF-8') . '"'; ?>
+
+ itemprop="thumbnail" />
+ image_first_caption)) :
+ ?>
+ image_first_caption, ENT_COMPAT, 'UTF-8'); ?>
+
+
+
- image_second)) : ?>
-
- float_second)) : ?>
- float_second == 'right' ? 'float-end' : 'float-start'; ?>
-
- image_second); ?>
- image_second_alt) && empty($images->image_second_alt_empty)
- ? ''
- : 'alt="' . htmlspecialchars($images->image_second_alt, ENT_COMPAT, 'UTF-8') . '"'; ?>
-
- itemprop="thumbnail" />
- image_second_caption)) : ?>
- image_second_caption, ENT_COMPAT, 'UTF-8'); ?>
-
-
-
+ image_second)) :
+ ?>
+
+ float_second)) :
+ ?>
+ float_second == 'right' ? 'float-end' : 'float-start'; ?>
+
+ image_second); ?>
+ image_second_alt) && empty($images->image_second_alt_empty)
+ ? ''
+ : 'alt="' . htmlspecialchars($images->image_second_alt, ENT_COMPAT, 'UTF-8') . '"'; ?>
+
+ itemprop="thumbnail" />
+ image_second_caption)) :
+ ?>
+ image_second_caption, ENT_COMPAT, 'UTF-8'); ?>
+
+
+
- item->description)) : ?>
- item->description; ?>
-
+ item->description)) :
+ ?>
+ item->description; ?>
+
-
+
-
-
- item->event->afterDisplayContent; ?>
+
+
+ item->event->afterDisplayContent; ?>
diff --git a/src/modules/mod_weblinks/mod_weblinks.xml b/src/modules/mod_weblinks/mod_weblinks.xml
index 9e5077b..64432e9 100644
--- a/src/modules/mod_weblinks/mod_weblinks.xml
+++ b/src/modules/mod_weblinks/mod_weblinks.xml
@@ -1,6 +1,7 @@
mod_weblinks
+ mod_weblinks
Joomla! Project
##DATE##
Copyright (C) 2005 - 2017 Open Source Matters. All rights reserved.
diff --git a/src/modules/mod_weblinks/services/provider.php b/src/modules/mod_weblinks/services/provider.php
index 75815ef..e663c2f 100644
--- a/src/modules/mod_weblinks/services/provider.php
+++ b/src/modules/mod_weblinks/services/provider.php
@@ -8,7 +8,9 @@
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
-defined('_JEXEC') or die;
+// phpcs:disable PSR1.Files.SideEffects
+\defined('_JEXEC') or die;
+// phpcs:enable PSR1.Files.SideEffects
use Joomla\CMS\Extension\Service\Provider\HelperFactory;
use Joomla\CMS\Extension\Service\Provider\Module;
@@ -22,20 +24,20 @@ use Joomla\DI\ServiceProviderInterface;
* @since __DEPLOY_VERSION__
*/
return new class () implements ServiceProviderInterface {
- /**
- * Registers the service provider with a DI container.
- *
- * @param Container $container The DI container.
- *
- * @return void
- *
- * @since __DEPLOY_VERSION__
- */
- public function register(Container $container)
- {
- $container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\Weblinks'));
- $container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\Weblinks\\Site\\Helper'));
+ /**
+ * Registers the service provider with a DI container.
+ *
+ * @param Container $container The DI container.
+ *
+ * @return void
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function register(Container $container)
+ {
+ $container->registerServiceProvider(new ModuleDispatcherFactory('\\Joomla\\Module\\Weblinks'));
+ $container->registerServiceProvider(new HelperFactory('\\Joomla\\Module\\Weblinks\\Site\\Helper'));
- $container->registerServiceProvider(new Module());
- }
+ $container->registerServiceProvider(new Module());
+ }
};
diff --git a/src/modules/mod_weblinks/src/Dispatcher/Dispatcher.php b/src/modules/mod_weblinks/src/Dispatcher/Dispatcher.php
index 9df4bd2..55a1ec6 100644
--- a/src/modules/mod_weblinks/src/Dispatcher/Dispatcher.php
+++ b/src/modules/mod_weblinks/src/Dispatcher/Dispatcher.php
@@ -14,9 +14,11 @@ use Joomla\CMS\Dispatcher\AbstractModuleDispatcher;
use Joomla\CMS\Helper\HelperFactoryAwareInterface;
use Joomla\CMS\Helper\HelperFactoryAwareTrait;
+// phpcs:disable PSR1.Files.SideEffects
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
+// phpcs:enable PSR1.Files.SideEffects
/**
* Dispatcher class for mod_weblinks
@@ -25,26 +27,26 @@ use Joomla\CMS\Helper\HelperFactoryAwareTrait;
*/
class Dispatcher extends AbstractModuleDispatcher implements HelperFactoryAwareInterface
{
- use HelperFactoryAwareTrait;
+ use HelperFactoryAwareTrait;
- /**
- * Returns the layout data.
- *
- * @return array
- *
- * @since __DEPLOY_VERSION__
- */
- protected function getLayoutData()
- {
- $data = parent::getLayoutData();
+ /**
+ * Returns the layout data.
+ *
+ * @return array
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ protected function getLayoutData()
+ {
+ $data = parent::getLayoutData();
- $data['list'] = $this->getHelperFactory()->getHelper('WeblinksHelper')->getWeblinks(
- $data['params'],
- $this->getApplication()
- );
+ $data['list'] = $this->getHelperFactory()->getHelper('WeblinksHelper')->getWeblinks(
+ $data['params'],
+ $this->getApplication()
+ );
- $data['moduleclass_sfx'] = htmlspecialchars($data['params']->get('moduleclass_sfx', ''));
+ $data['moduleclass_sfx'] = htmlspecialchars($data['params']->get('moduleclass_sfx', ''));
- return $data;
- }
+ return $data;
+ }
}
diff --git a/src/modules/mod_weblinks/src/Helper/WeblinksHelper.php b/src/modules/mod_weblinks/src/Helper/WeblinksHelper.php
index c476ea9..9a1c773 100644
--- a/src/modules/mod_weblinks/src/Helper/WeblinksHelper.php
+++ b/src/modules/mod_weblinks/src/Helper/WeblinksHelper.php
@@ -1,4 +1,5 @@
bootComponent('com_weblinks')->getMVCFactory()
- ->createModel('Category', 'Site', ['ignore_request' => true]);
+ /**
+ * Retrieve list of weblinks
+ *
+ * @param Registry $params The module parameters
+ * @param CMSApplicationInterface $app The application
+ *
+ * @return array Array containing all the weblinks.
+ *
+ * @since __DEPLOY_VERSION__
+ **/
+ public function getWeblinks($params, $app)
+ {
+ // @var \Joomla\Component\Weblinks\Site\Model\CategoryModel $model
+ $model = $app->bootComponent('com_weblinks')->getMVCFactory()
+ ->createModel('Category', 'Site', ['ignore_request' => true]);
- // Set application parameters in model
- $cParams = ComponentHelper::getParams('com_weblinks');
- $model->setState('params', $cParams);
+ // Set application parameters in model
+ $cParams = ComponentHelper::getParams('com_weblinks');
+ $model->setState('params', $cParams);
- // Set the filters based on the module params
- $model->setState('list.start', 0);
- $model->setState('list.limit', (int) $params->get('count', 5));
+ // Set the filters based on the module params
+ $model->setState('list.start', 0);
+ $model->setState('list.limit', (int) $params->get('count', 5));
- $model->setState('filter.state', 1);
- $model->setState('filter.publish_date', true);
+ $model->setState('filter.state', 1);
+ $model->setState('filter.publish_date', true);
- // Access filter
- $access = !ComponentHelper::getParams('com_weblinks')->get('show_noauth');
- $model->setState('filter.access', $access);
+ // Access filter
+ $access = !ComponentHelper::getParams('com_weblinks')->get('show_noauth');
+ $model->setState('filter.access', $access);
- $ordering = $params->get('ordering', 'ordering');
- $model->setState('list.ordering', $ordering == 'order' ? 'ordering' : $ordering);
- $model->setState('list.direction', $params->get('direction', 'asc'));
+ $ordering = $params->get('ordering', 'ordering');
+ $model->setState('list.ordering', $ordering == 'order' ? 'ordering' : $ordering);
+ $model->setState('list.direction', $params->get('direction', 'asc'));
- $catid = (int) $params->get('catid', 0);
- $model->setState('category.id', $catid);
- $model->setState('category.group', $params->get('groupby', 0));
- $model->setState('category.ordering', $params->get('groupby_ordering', 'c.lft'));
- $model->setState('category.direction', $params->get('groupby_direction', 'ASC'));
+ $catid = (int) $params->get('catid', 0);
+ $model->setState('category.id', $catid);
+ $model->setState('category.group', $params->get('groupby', 0));
+ $model->setState('category.ordering', $params->get('groupby_ordering', 'c.lft'));
+ $model->setState('category.direction', $params->get('groupby_direction', 'ASC'));
- // Create query object
- $db = $model->getDbo();
- $query = $db->getQuery(true);
+ // Create query object
+ $db = $model->getDbo();
+ $query = $db->getQuery(true);
- $case_when1 = ' CASE WHEN ';
- $case_when1 .= $query->charLength('a.alias', '!=', '0');
- $case_when1 .= ' THEN ';
- $a_id = $query->castAs('CHAR', 'a.id');
- $case_when1 .= $query->concatenate([$a_id, 'a.alias'], ':');
- $case_when1 .= ' ELSE ';
- $case_when1 .= $a_id . ' END as slug';
+ $case_when1 = ' CASE WHEN ';
+ $case_when1 .= $query->charLength('a.alias', '!=', '0');
+ $case_when1 .= ' THEN ';
+ $a_id = $query->castAs('CHAR', 'a.id');
+ $case_when1 .= $query->concatenate([$a_id, 'a.alias'], ':');
+ $case_when1 .= ' ELSE ';
+ $case_when1 .= $a_id . ' END as slug';
- $case_when2 = ' CASE WHEN ';
- $case_when2 .= $query->charLength('c.alias', '!=', '0');
- $case_when2 .= ' THEN ';
- $c_id = $query->castAs('CHAR', 'c.id');
- $case_when2 .= $query->concatenate([$c_id, 'c.alias'], ':');
- $case_when2 .= ' ELSE ';
- $case_when2 .= $c_id . ' END as catslug';
+ $case_when2 = ' CASE WHEN ';
+ $case_when2 .= $query->charLength('c.alias', '!=', '0');
+ $case_when2 .= ' THEN ';
+ $c_id = $query->castAs('CHAR', 'c.id');
+ $case_when2 .= $query->concatenate([$c_id, 'c.alias'], ':');
+ $case_when2 .= ' ELSE ';
+ $case_when2 .= $c_id . ' END as catslug';
- $model->setState(
- 'list.select',
- 'a.*, c.description AS c_description, c.published AS c_published,' . $case_when1 . ',' . $case_when2
- );
+ $model->setState(
+ 'list.select',
+ 'a.*, c.description AS c_description, c.published AS c_published,' . $case_when1 . ',' . $case_when2
+ );
- $model->setState('filter.c.published', 1);
+ $model->setState('filter.c.published', 1);
- // Filter by language
- $model->setState('filter.language', $app->getLanguageFilter());
+ // Filter by language
+ $model->setState('filter.language', $app->getLanguageFilter());
- $items = $model->getItems();
+ $items = $model->getItems();
- if ($items)
- {
- foreach ($items as $item)
- {
- $temp = $item->params;
- $item->params = clone $cParams;
- $item->params->merge($temp);
+ if ($items) {
+ foreach ($items as $item) {
+ $temp = $item->params;
+ $item->params = clone $cParams;
+ $item->params->merge($temp);
- if ($item->params->get('count_clicks', 1) == 1)
- {
- $item->link = Route::_('index.php?option=com_weblinks&task=weblink.go&catid=' . $item->catslug . '&id=' . $item->slug);
- }
- else
- {
- $item->link = $item->url;
- }
- }
+ if ($item->params->get('count_clicks', 1) == 1) {
+ $item->link = Route::_('index.php?option=com_weblinks&task=weblink.go&catid=' . $item->catslug . '&id=' . $item->slug);
+ } else {
+ $item->link = $item->url;
+ }
+ }
- return $items;
- }
+ return $items;
+ }
- return [];
- }
+ return [];
+ }
- /**
- * Retrieve list of weblinks
- *
- * @param Registry $params The module parameters
- * @param CMSApplicationInterface $app The application
- *
- * @return mixed Null if no weblinks based on input parameters else an array containing all the weblinks.
- *
- * @since 1.5
- *
- * @deprecated 5.0 Use the none static function getWeblinks
- **/
- public static function getList($params, $app)
- {
- return (new self())->getWeblinks($params, $app);
- }
+ /**
+ * Retrieve list of weblinks
+ *
+ * @param Registry $params The module parameters
+ * @param CMSApplicationInterface $app The application
+ *
+ * @return mixed Null if no weblinks based on input parameters else an array containing all the weblinks.
+ *
+ * @since 1.5
+ *
+ * @deprecated 5.0 Use the none static function getWeblinks
+ **/
+ public static function getList($params, $app)
+ {
+ return (new self())->getWeblinks($params, $app);
+ }
}
diff --git a/src/modules/mod_weblinks/tmpl/default.php b/src/modules/mod_weblinks/tmpl/default.php
index 0cac7fb..e24b891 100644
--- a/src/modules/mod_weblinks/tmpl/default.php
+++ b/src/modules/mod_weblinks/tmpl/default.php
@@ -1,4 +1,5 @@
-get('groupby', 0)) : ?>
-
- get('groupby_columns', 3); ?>
-
- $l->catid, 'title' => $l->category_title); ?>
-
-
- $cat) : ?>
-
-
- catid == $cat['catid']) : ?>
-
-
-
- 1) :?>
-
-
-
-
-
- get('groupby_showtitle', 1)) :?>
-
- ;
-
-
-
-
- link;
- $width = (int) $item->params->get('width', 600);
- $height = (int) $item->params->get('height', 500);
+get('groupby', 0)) :
+ ?>
+
+ get('groupby_columns', 3); ?>
+
+ $l->catid, 'title' => $l->category_title); ?>
+
+
+ $cat) :
+ ?>
+
+
+ catid == $cat['catid']) :
+ ?>
+
+
+
+ 1) :
+ ?>
+
+
+
+
+
+ get('groupby_showtitle', 1)) :
+ ?>
+
+ ;
+
+
+
+
+ link;
+ $width = (int) $item->params->get('width', 600);
+ $height = (int) $item->params->get('height', 500);
+ switch ($item->params->get('target')) {
+ case 1:
+ // Open in a new window
+ echo '
' .
+ htmlspecialchars($item->title, ENT_COMPAT, 'UTF-8') . ' ';
+ break;
+ case 2:
+ // Open in a popup window
+ $attribs = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=' . $width . ',height=' . $height;
+ echo "
" .
+ htmlspecialchars($item->title, ENT_COMPAT, 'UTF-8') . ' ';
- switch ($item->params->get('target'))
- {
- case 1:
- // Open in a new window
- echo '
' .
- htmlspecialchars($item->title, ENT_COMPAT, 'UTF-8') . ' ';
- break;
- case 2:
- // Open in a popup window
- $attribs = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=' . $width . ',height=' . $height;
- echo "
" .
- htmlspecialchars($item->title, ENT_COMPAT, 'UTF-8') . ' ';
- break;
- case 3:
- // Open in a modal window
- $modalId = 'weblink-item-modal-' . $item->id;
- $modalParams['title'] = htmlspecialchars($item->title, ENT_COMPAT, 'UTF-8');
- $modalParams['url'] = $link;
- $modalParams['height'] = '100%';
- $modalParams['width'] = '100%';
- $modalParams['bodyHeight'] = 70;
- $modalParams['modalWidth'] = 80;
- echo HTMLHelper::_('bootstrap.renderModal', $modalId, $modalParams);
- echo '
- ' . $item->title . '
- ';
- break;
- default:
- // Open in parent window
- echo '
' .
- htmlspecialchars($item->title, ENT_COMPAT, 'UTF-8') . ' ';
- break;
- }
- ?>
-
- get('description', 0) ? '
' . $item->description . '
' : ''; ?>
- get('hits', 0)) : ?>
-
- hits . ' ' . Text::_('MOD_WEBLINKS_HITS'); ?>
-
-
-
-
-
- 1) :?>
-
-
-
-
-
-
-
-
-
-
-
- link;
- $width = (int) $item->params->get('width', 600);
- $height = (int) $item->params->get('height', 500);
+ break;
+ case 3:
+ // Open in a modal window
+ $modalId = 'weblink-item-modal-' . $item->id;
+ $modalParams['title'] = htmlspecialchars($item->title, ENT_COMPAT, 'UTF-8');
+ $modalParams['url'] = $link;
+ $modalParams['height'] = '100%';
+ $modalParams['width'] = '100%';
+ $modalParams['bodyHeight'] = 70;
+ $modalParams['modalWidth'] = 80;
+ echo HTMLHelper::_('bootstrap.renderModal', $modalId, $modalParams);
+ echo '
+ ' . $item->title . ' ';
- switch ($item->params->get('target'))
- {
- case 1:
- // Open in a new window
- echo '
' .
- htmlspecialchars($item->title, ENT_COMPAT, 'UTF-8') . ' ';
- break;
- case 2:
- // Open in a popup window
- $attribs = 'toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=' . $width . ',height=' . $height;
- echo "
" .
- htmlspecialchars($item->title, ENT_COMPAT, 'UTF-8') . ' ';
- break;
- case 3:
- // Open in a modal window
- $modalId = 'weblink-item-modal-' . $item->id;
- $modalParams['title'] = htmlspecialchars($item->title, ENT_COMPAT, 'UTF-8');
- $modalParams['url'] = $link;
- $modalParams['height'] = '100%';
- $modalParams['width'] = '100%';
- $modalParams['bodyHeight'] = 70;
- $modalParams['modalWidth'] = 80;
- echo HTMLHelper::_('bootstrap.renderModal', $modalId, $modalParams);
- echo '
+ break;
+ default:
+ // Open in parent window
+ echo '' .
+ htmlspecialchars($item->title, ENT_COMPAT, 'UTF-8') . ' ';
+
+ break;
+ }
+ ?>
+
+ get('description', 0) ? '
' . $item->description . '
' : ''; ?>
+ get('hits', 0)) :
+ ?>
+
+ hits . ' ' . Text::_('MOD_WEBLINKS_HITS'); ?>
+
+
+
+
+
+ 1) :
+ ?>
+
+
+
+
+
+
+
+
+
diff --git a/src/plugins/editors-xtd/weblink/services/provider.php b/src/plugins/editors-xtd/weblink/services/provider.php
index 418d626..6789c09 100644
--- a/src/plugins/editors-xtd/weblink/services/provider.php
+++ b/src/plugins/editors-xtd/weblink/services/provider.php
@@ -8,7 +8,9 @@
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
-defined('_JEXEC') or die;
+// phpcs:disable PSR1.Files.SideEffects
+\defined('_JEXEC') or die;
+// phpcs:enable PSR1.Files.SideEffects
use Joomla\CMS\Extension\PluginInterface;
use Joomla\CMS\Factory;
@@ -19,29 +21,29 @@ use Joomla\Event\DispatcherInterface;
use Joomla\Plugin\EditorsXtd\Weblink\Extension\Weblink;
return new class () implements ServiceProviderInterface {
- /**
- * Registers the service provider with a DI container.
- *
- * @param Container $container The DI container.
- *
- * @return void
- *
- * @since __DEPLOY_VERSION__
- */
- public function register(Container $container)
- {
- $container->set(
- PluginInterface::class,
- function (Container $container) {
- $app = Factory::getApplication();
- $dispatcher = $container->get(DispatcherInterface::class);
+ /**
+ * Registers the service provider with a DI container.
+ *
+ * @param Container $container The DI container.
+ *
+ * @return void
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function register(Container $container)
+ {
+ $container->set(
+ PluginInterface::class,
+ function (Container $container) {
+ $app = Factory::getApplication();
+ $dispatcher = $container->get(DispatcherInterface::class);
- return new Weblink(
- $dispatcher,
- (array) PluginHelper::getPlugin('editors-xtd', 'weblink'),
- $app
- );
- }
- );
- }
+ return new Weblink(
+ $dispatcher,
+ (array) PluginHelper::getPlugin('editors-xtd', 'weblink'),
+ $app
+ );
+ }
+ );
+ }
};
diff --git a/src/plugins/editors-xtd/weblink/src/Extension/Weblink.php b/src/plugins/editors-xtd/weblink/src/Extension/Weblink.php
index de0ce28..3b19457 100644
--- a/src/plugins/editors-xtd/weblink/src/Extension/Weblink.php
+++ b/src/plugins/editors-xtd/weblink/src/Extension/Weblink.php
@@ -1,4 +1,5 @@
setApplication($application);
- }
+ $this->setApplication($application);
+ }
- /**
- * Display the button
- *
- * @param string $name The name of the button to add
- *
- * @return CMSObject The button options as JObject
- *
- * @since __DEPLOY_VERSION__
- */
- public function onDisplay($name)
- {
- $user = $this->getApplication()->getIdentity();
+ /**
+ * Display the button
+ *
+ * @param string $name The name of the button to add
+ *
+ * @return CMSObject The button options as JObject
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function onDisplay($name)
+ {
+ $user = $this->getApplication()->getIdentity();
- if ($user->authorise('core.create', 'com_weblinks')
- || $user->authorise('core.edit', 'com_weblinks')
- || $user->authorise('core.edit.own', 'com_weblinks'))
- {
- // The URL for the weblinks list
- $link = 'index.php?option=com_weblinks&view=weblinks&layout=modal&tmpl=component&'
- . Session::getFormToken() . '=1&editor=' . $name;
+ if (
+ $user->authorise('core.create', 'com_weblinks')
+ || $user->authorise('core.edit', 'com_weblinks')
+ || $user->authorise('core.edit.own', 'com_weblinks')
+ ) {
+ // The URL for the weblinks list
+ $link = 'index.php?option=com_weblinks&view=weblinks&layout=modal&tmpl=component&'
+ . Session::getFormToken() . '=1&editor=' . $name;
- $button = new CMSObject;
- $button->modal = true;
- $button->link = $link;
- $button->text = Text::_('PLG_EDITORS-XTD_WEBLINK_BUTTON_WEBLINK');
- $button->name = $this->_type . '_' . $this->_name;
- $button->icon = 'globe';
- $button->iconSVG = '
+ $button = new CMSObject();
+ $button->modal = true;
+ $button->link = $link;
+ $button->text = Text::_('PLG_EDITORS-XTD_WEBLINK_BUTTON_WEBLINK');
+ $button->name = $this->_type . '_' . $this->_name;
+ $button->icon = 'globe';
+ // phpcs:disable Generic.Files.LineLength
+ $button->iconSVG = '
';
+ // phpcs:enable Generic.Files.LineLength
+ $button->options = [
+ 'height' => '300px',
+ 'width' => '800px',
+ 'bodyHeight' => '70',
+ 'modalWidth' => '80',
+ ];
- $button->options = [
- 'height' => '300px',
- 'width' => '800px',
- 'bodyHeight' => '70',
- 'modalWidth' => '80',
- ];
-
- return $button;
- }
- }
+ return $button;
+ }
+ }
}
diff --git a/src/plugins/finder/weblinks/services/provider.php b/src/plugins/finder/weblinks/services/provider.php
index 5147ef3..1e724df 100644
--- a/src/plugins/finder/weblinks/services/provider.php
+++ b/src/plugins/finder/weblinks/services/provider.php
@@ -8,7 +8,9 @@
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
-defined('_JEXEC') or die;
+// phpcs:disable PSR1.Files.SideEffects
+\defined('_JEXEC') or die;
+// phpcs:enable PSR1.Files.SideEffects
use Joomla\CMS\Extension\PluginInterface;
use Joomla\CMS\Plugin\PluginHelper;
@@ -19,29 +21,29 @@ use Joomla\Event\DispatcherInterface;
use Joomla\Plugin\Finder\Weblinks\Extension\Weblinks;
return new class () implements ServiceProviderInterface {
- /**
- * Registers the service provider with a DI container.
- *
- * @param Container $container The DI container.
- *
- * @return void
- *
- * @since __DEPLOY_VERSION__
- */
- public function register(Container $container)
- {
- $container->set(
- PluginInterface::class,
- function (Container $container) {
- $dispatcher = $container->get(DispatcherInterface::class);
- $database = $container->get(DatabaseInterface::class);
+ /**
+ * Registers the service provider with a DI container.
+ *
+ * @param Container $container The DI container.
+ *
+ * @return void
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function register(Container $container)
+ {
+ $container->set(
+ PluginInterface::class,
+ function (Container $container) {
+ $dispatcher = $container->get(DispatcherInterface::class);
+ $database = $container->get(DatabaseInterface::class);
- return new Weblinks(
- $dispatcher,
- (array) PluginHelper::getPlugin('finder', 'weblinks'),
- $database
- );
- }
- );
- }
+ return new Weblinks(
+ $dispatcher,
+ (array) PluginHelper::getPlugin('finder', 'weblinks'),
+ $database
+ );
+ }
+ );
+ }
};
diff --git a/src/plugins/finder/weblinks/src/Extension/Weblinks.php b/src/plugins/finder/weblinks/src/Extension/Weblinks.php
index 1144c53..0341ce8 100644
--- a/src/plugins/finder/weblinks/src/Extension/Weblinks.php
+++ b/src/plugins/finder/weblinks/src/Extension/Weblinks.php
@@ -1,4 +1,5 @@
setDatabase($database);
- }
+ $this->setDatabase($database);
+ }
- /**
- * Method to update the item link information when the item category is
- * changed. This is fired when the item category is published or unpublished
- * from the list view.
- *
- * @param string $extension The extension whose category has been updated.
- * @param array $pks An array of primary key ids of the content that has changed state.
- * @param integer $value The value of the state that the content has been changed to.
- *
- * @return void
- *
- * @since 2.5
- */
- public function onFinderCategoryChangeState($extension, $pks, $value)
- {
- // Make sure we're handling com_weblinks categories.
- if ($extension == 'com_weblinks')
- {
- $this->categoryStateChange($pks, $value);
- }
- }
+ /**
+ * Method to update the item link information when the item category is
+ * changed. This is fired when the item category is published or unpublished
+ * from the list view.
+ *
+ * @param string $extension The extension whose category has been updated.
+ * @param array $pks An array of primary key ids of the content that has changed state.
+ * @param integer $value The value of the state that the content has been changed to.
+ *
+ * @return void
+ *
+ * @since 2.5
+ */
+ public function onFinderCategoryChangeState($extension, $pks, $value)
+ {
+ // Make sure we're handling com_weblinks categories.
+ if ($extension == 'com_weblinks') {
+ $this->categoryStateChange($pks, $value);
+ }
+ }
- /**
- * Method to remove the link information for items that have been deleted.
- *
- * @param string $context The context of the action being performed.
- * @param Table $table A JTable object containing the record to be deleted.
- *
- * @return boolean True on success.
- *
- * @throws \Exception on database error.
- * @since 2.5
- */
- public function onFinderAfterDelete($context, $table)
- {
- if ($context == 'com_weblinks.weblink')
- {
- $id = $table->id;
- }
- elseif ($context == 'com_finder.index')
- {
- $id = $table->link_id;
- }
- else
- {
- return true;
- }
+ /**
+ * Method to remove the link information for items that have been deleted.
+ *
+ * @param string $context The context of the action being performed.
+ * @param Table $table A JTable object containing the record to be deleted.
+ *
+ * @return boolean True on success.
+ *
+ * @throws \Exception on database error.
+ * @since 2.5
+ */
+ public function onFinderAfterDelete($context, $table)
+ {
+ if ($context == 'com_weblinks.weblink') {
+ $id = $table->id;
+ } elseif ($context == 'com_finder.index') {
+ $id = $table->link_id;
+ } else {
+ return true;
+ }
- // Remove the item from the index.
- return $this->remove($id);
- }
+ // Remove the item from the index.
+ return $this->remove($id);
+ }
- /**
- * Smart Search after content save method.
- * Reindexes the link information for a weblink that has been saved.
- * It also makes adjustments if the access level of a weblink item or
- * the category to which it belongs has been changed.
- *
- * @param string $context The context of the content passed to the plugin.
- * @param Table $row A JTable object.
- * @param boolean $isNew True if the content has just been created.
- *
- * @return boolean True on success.
- *
- * @throws \Exception on database error.
- * @since 2.5
- */
- public function onFinderAfterSave($context, $row, $isNew)
- {
- // We only want to handle web links here. We need to handle front end and back end editing.
- if ($context == 'com_weblinks.weblink' || $context == 'com_weblinks.form')
- {
- // Check if the access levels are different.
- if (!$isNew && $this->old_access != $row->access)
- {
- // Process the change.
- $this->itemAccessChange($row);
- }
+ /**
+ * Smart Search after content save method.
+ * Reindexes the link information for a weblink that has been saved.
+ * It also makes adjustments if the access level of a weblink item or
+ * the category to which it belongs has been changed.
+ *
+ * @param string $context The context of the content passed to the plugin.
+ * @param Table $row A JTable object.
+ * @param boolean $isNew True if the content has just been created.
+ *
+ * @return boolean True on success.
+ *
+ * @throws \Exception on database error.
+ * @since 2.5
+ */
+ public function onFinderAfterSave($context, $row, $isNew)
+ {
+ // We only want to handle web links here. We need to handle front end and back end editing.
+ if ($context == 'com_weblinks.weblink' || $context == 'com_weblinks.form') {
+ // Check if the access levels are different.
+ if (!$isNew && $this->old_access != $row->access) {
+ // Process the change.
+ $this->itemAccessChange($row);
+ }
- // Reindex the item.
- $this->reindex($row->id);
- }
+ // Reindex the item.
+ $this->reindex($row->id);
+ }
- // Check for access changes in the category.
- if ($context == 'com_categories.category')
- {
- // Check if the access levels are different.
- if (!$isNew && $this->old_cataccess != $row->access)
- {
- $this->categoryAccessChange($row);
- }
- }
+ // Check for access changes in the category.
+ if ($context == 'com_categories.category') {
+ // Check if the access levels are different.
+ if (!$isNew && $this->old_cataccess != $row->access) {
+ $this->categoryAccessChange($row);
+ }
+ }
- return true;
- }
+ return true;
+ }
- /**
- * Smart Search before content save method.
- * This event is fired before the data is actually saved.
- *
- * @param string $context The context of the content passed to the plugin.
- * @param Table $row A JTable object.
- * @param boolean $isNew True if the content is just about to be created.
- *
- * @return boolean True on success.
- *
- * @throws \Exception on database error.
- * @since 2.5
- */
- public function onFinderBeforeSave($context, $row, $isNew)
- {
- // We only want to handle web links here.
- if ($context == 'com_weblinks.weblink' || $context == 'com_weblinks.form')
- {
- // Query the database for the old access level if the item isn't new.
- if (!$isNew)
- {
- $this->checkItemAccess($row);
- }
- }
+ /**
+ * Smart Search before content save method.
+ * This event is fired before the data is actually saved.
+ *
+ * @param string $context The context of the content passed to the plugin.
+ * @param Table $row A JTable object.
+ * @param boolean $isNew True if the content is just about to be created.
+ *
+ * @return boolean True on success.
+ *
+ * @throws \Exception on database error.
+ * @since 2.5
+ */
+ public function onFinderBeforeSave($context, $row, $isNew)
+ {
+ // We only want to handle web links here.
+ if ($context == 'com_weblinks.weblink' || $context == 'com_weblinks.form') {
+ // Query the database for the old access level if the item isn't new.
+ if (!$isNew) {
+ $this->checkItemAccess($row);
+ }
+ }
- // Check for access levels from the category.
- if ($context == 'com_categories.category')
- {
- // Query the database for the old access level if the item isn't new.
- if (!$isNew)
- {
- $this->checkCategoryAccess($row);
- }
- }
+ // Check for access levels from the category.
+ if ($context == 'com_categories.category') {
+ // Query the database for the old access level if the item isn't new.
+ if (!$isNew) {
+ $this->checkCategoryAccess($row);
+ }
+ }
- return true;
- }
+ return true;
+ }
- /**
- * Method to update the link information for items that have been changed
- * from outside the edit screen. This is fired when the item is published,
- * unpublished, archived, or unarchived from the list view.
- *
- * @param string $context The context for the content passed to the plugin.
- * @param array $pks An array of primary key ids of the content that has changed state.
- * @param integer $value The value of the state that the content has been changed to.
- *
- * @return void
- *
- * @since 2.5
- */
- public function onFinderChangeState($context, $pks, $value)
- {
- // We only want to handle web links here.
- if ($context == 'com_weblinks.weblink' || $context == 'com_weblinks.form')
- {
- $this->itemStateChange($pks, $value);
- }
+ /**
+ * Method to update the link information for items that have been changed
+ * from outside the edit screen. This is fired when the item is published,
+ * unpublished, archived, or unarchived from the list view.
+ *
+ * @param string $context The context for the content passed to the plugin.
+ * @param array $pks An array of primary key ids of the content that has changed state.
+ * @param integer $value The value of the state that the content has been changed to.
+ *
+ * @return void
+ *
+ * @since 2.5
+ */
+ public function onFinderChangeState($context, $pks, $value)
+ {
+ // We only want to handle web links here.
+ if ($context == 'com_weblinks.weblink' || $context == 'com_weblinks.form') {
+ $this->itemStateChange($pks, $value);
+ }
- // Handle when the plugin is disabled.
- if ($context == 'com_plugins.plugin' && $value === 0)
- {
- $this->pluginDisable($pks);
- }
- }
+ // Handle when the plugin is disabled.
+ if ($context == 'com_plugins.plugin' && $value === 0) {
+ $this->pluginDisable($pks);
+ }
+ }
- /**
- * Method to index an item. The item must be a FinderIndexerResult object.
- *
- * @param Result $item The item to index as an FinderIndexerResult object.
- *
- * @return void
- *
- * @throws \Exception on database error.
- * @since 2.5
- */
- protected function index(Result $item)
- {
- // Check if the extension is enabled
- if (ComponentHelper::isEnabled($this->extension) == false)
- {
- return;
- }
+ /**
+ * Method to index an item. The item must be a FinderIndexerResult object.
+ *
+ * @param Result $item The item to index as an FinderIndexerResult object.
+ *
+ * @return void
+ *
+ * @throws \Exception on database error.
+ * @since 2.5
+ */
+ protected function index(Result $item)
+ {
+ // Check if the extension is enabled
+ if (ComponentHelper::isEnabled($this->extension) == false) {
+ return;
+ }
- $item->setLanguage();
+ $item->setLanguage();
- // Initialise the item parameters.
- $item->params = new Registry($item->params);
- $item->metadata = new Registry($item->metadata);
+ // Initialise the item parameters.
+ $item->params = new Registry($item->params);
+ $item->metadata = new Registry($item->metadata);
- // Build the necessary route and path information.
- $item->url = $this->getURL($item->id, $this->extension, $this->layout);
- $item->route = RouteHelper::getWeblinkRoute($item->slug, $item->catslug, $item->language);
+ // Build the necessary route and path information.
+ $item->url = $this->getURL($item->id, $this->extension, $this->layout);
+ $item->route = RouteHelper::getWeblinkRoute($item->slug, $item->catslug, $item->language);
- /*
- * Add the meta-data processing instructions based on the newsfeeds
- * configuration parameters.
- */
- // Add the meta-author.
- $item->metaauthor = $item->metadata->get('author');
+ /*
+ * Add the meta-data processing instructions based on the newsfeeds
+ * configuration parameters.
+ */
+ // Add the meta-author.
+ $item->metaauthor = $item->metadata->get('author');
- // Handle the link to the meta-data.
- $item->addInstruction(Indexer::META_CONTEXT, 'link');
- $item->addInstruction(Indexer::META_CONTEXT, 'metakey');
- $item->addInstruction(Indexer::META_CONTEXT, 'metadesc');
- $item->addInstruction(Indexer::META_CONTEXT, 'metaauthor');
- $item->addInstruction(Indexer::META_CONTEXT, 'author');
- $item->addInstruction(Indexer::META_CONTEXT, 'created_by_alias');
+ // Handle the link to the meta-data.
+ $item->addInstruction(Indexer::META_CONTEXT, 'link');
+ $item->addInstruction(Indexer::META_CONTEXT, 'metakey');
+ $item->addInstruction(Indexer::META_CONTEXT, 'metadesc');
+ $item->addInstruction(Indexer::META_CONTEXT, 'metaauthor');
+ $item->addInstruction(Indexer::META_CONTEXT, 'author');
+ $item->addInstruction(Indexer::META_CONTEXT, 'created_by_alias');
- // Translate the state. Weblinks should only be published if the category is published and also ensure that 'state' for trashed items is set to zero
- $item->state = $this->translateState($item->state, $item->cat_state);
+ // Translate the state. Weblinks should only be published if the category is published and also ensure that 'state' for trashed items is set to zero
+ $item->state = $this->translateState($item->state, $item->cat_state);
- // Add the type taxonomy data.
- $item->addTaxonomy('Type', 'Web Link');
+ // Add the type taxonomy data.
+ $item->addTaxonomy('Type', 'Web Link');
- // Add the category taxonomy data.
- $categories = Categories::getInstance('com_weblinks', ['published' => false, 'access' => false]);
- $category = $categories->get($item->catid);
+ // Add the category taxonomy data.
+ $categories = Categories::getInstance('com_weblinks', ['published' => false, 'access' => false]);
+ $category = $categories->get($item->catid);
- // Category does not exist, stop here
- if (!$category)
- {
- return;
- }
+ // Category does not exist, stop here
+ if (!$category) {
+ return;
+ }
- $item->addNestedTaxonomy('Category', $category, $this->translateState($category->published), $category->access, $category->language);
+ $item->addNestedTaxonomy('Category', $category, $this->translateState($category->published), $category->access, $category->language);
- // Add the language taxonomy data.
- $item->addTaxonomy('Language', $item->language);
+ // Add the language taxonomy data.
+ $item->addTaxonomy('Language', $item->language);
- // Get content extras.
- Helper::getContentExtras($item);
+ // Get content extras.
+ Helper::getContentExtras($item);
- // Index the item.
- $this->indexer->index($item);
- }
+ // Index the item.
+ $this->indexer->index($item);
+ }
- /**
- * Method to setup the indexer to be run.
- *
- * @return boolean True on success.
- *
- * @since 2.5
- */
- protected function setup()
- {
- return true;
- }
+ /**
+ * Method to setup the indexer to be run.
+ *
+ * @return boolean True on success.
+ *
+ * @since 2.5
+ */
+ protected function setup()
+ {
+ return true;
+ }
- /**
- * Method to get the SQL query used to retrieve the list of content items.
- *
- * @param mixed $query A JDatabaseQuery object or null.
- *
- * @return DatabaseQuery A database object.
- *
- * @since 2.5
- */
- protected function getListQuery($query = null)
- {
- $db = $this->getDatabase();
+ /**
+ * Method to get the SQL query used to retrieve the list of content items.
+ *
+ * @param mixed $query A JDatabaseQuery object or null.
+ *
+ * @return DatabaseQuery A database object.
+ *
+ * @since 2.5
+ */
+ protected function getListQuery($query = null)
+ {
+ $db = $this->getDatabase();
- // Check if we can use the supplied SQL query.
- $query = $query instanceof DatabaseQuery ? $query : $db->getQuery(true)
- ->select('a.id, a.catid, a.title, a.alias, a.url AS link, a.description AS summary')
- ->select('a.metakey, a.metadesc, a.metadata, a.language, a.access, a.ordering')
- ->select('a.created_by_alias, a.modified, a.modified_by')
- ->select('a.publish_up AS publish_start_date, a.publish_down AS publish_end_date')
- ->select('a.state AS state, a.created AS start_date, a.params')
- ->select('c.title AS category, c.published AS cat_state, c.access AS cat_access');
+ // Check if we can use the supplied SQL query.
+ $query = $query instanceof DatabaseQuery ? $query : $db->getQuery(true)
+ ->select('a.id, a.catid, a.title, a.alias, a.url AS link, a.description AS summary')
+ ->select('a.metakey, a.metadesc, a.metadata, a.language, a.access, a.ordering')
+ ->select('a.created_by_alias, a.modified, a.modified_by')
+ ->select('a.publish_up AS publish_start_date, a.publish_down AS publish_end_date')
+ ->select('a.state AS state, a.created AS start_date, a.params')
+ ->select('c.title AS category, c.published AS cat_state, c.access AS cat_access');
- // Handle the alias CASE WHEN portion of the query.
- $case_when_item_alias = ' CASE WHEN ';
- $case_when_item_alias .= $query->charLength('a.alias', '!=', '0');
- $case_when_item_alias .= ' THEN ';
- $a_id = $query->castAs('CHAR', 'a.id');
- $case_when_item_alias .= $query->concatenate([$a_id, 'a.alias'], ':');
- $case_when_item_alias .= ' ELSE ';
- $case_when_item_alias .= $a_id . ' END as slug';
- $query->select($case_when_item_alias);
+ // Handle the alias CASE WHEN portion of the query.
+ $case_when_item_alias = ' CASE WHEN ';
+ $case_when_item_alias .= $query->charLength('a.alias', '!=', '0');
+ $case_when_item_alias .= ' THEN ';
+ $a_id = $query->castAs('CHAR', 'a.id');
+ $case_when_item_alias .= $query->concatenate([$a_id, 'a.alias'], ':');
+ $case_when_item_alias .= ' ELSE ';
+ $case_when_item_alias .= $a_id . ' END as slug';
+ $query->select($case_when_item_alias);
- $case_when_category_alias = ' CASE WHEN ';
- $case_when_category_alias .= $query->charLength('c.alias', '!=', '0');
- $case_when_category_alias .= ' THEN ';
- $c_id = $query->castAs('CHAR', 'c.id');
- $case_when_category_alias .= $query->concatenate([$c_id, 'c.alias'], ':');
- $case_when_category_alias .= ' ELSE ';
- $case_when_category_alias .= $c_id . ' END as catslug';
- $query->select($case_when_category_alias)
- ->from('#__weblinks AS a')
- ->join('LEFT', '#__categories AS c ON c.id = a.catid');
+ $case_when_category_alias = ' CASE WHEN ';
+ $case_when_category_alias .= $query->charLength('c.alias', '!=', '0');
+ $case_when_category_alias .= ' THEN ';
+ $c_id = $query->castAs('CHAR', 'c.id');
+ $case_when_category_alias .= $query->concatenate([$c_id, 'c.alias'], ':');
+ $case_when_category_alias .= ' ELSE ';
+ $case_when_category_alias .= $c_id . ' END as catslug';
+ $query->select($case_when_category_alias)
+ ->from('#__weblinks AS a')
+ ->join('LEFT', '#__categories AS c ON c.id = a.catid');
- return $query;
- }
+ return $query;
+ }
- /**
- * Method to get the query clause for getting items to update by time.
- *
- * @param string $time The modified timestamp.
- *
- * @return DatabaseQuery A database object.
- *
- * @since 2.5
- */
- protected function getUpdateQueryByTime($time)
- {
- // Build an SQL query based on the modified time.
- $db = $this->getDatabase();
- $query = $db->getQuery(true)
- ->where('a.date >= ' . $db->quote($time));
+ /**
+ * Method to get the query clause for getting items to update by time.
+ *
+ * @param string $time The modified timestamp.
+ *
+ * @return DatabaseQuery A database object.
+ *
+ * @since 2.5
+ */
+ protected function getUpdateQueryByTime($time)
+ {
+ // Build an SQL query based on the modified time.
+ $db = $this->getDatabase();
+ $query = $db->getQuery(true)
+ ->where('a.date >= ' . $db->quote($time));
- return $query;
- }
+ return $query;
+ }
}
diff --git a/src/plugins/search/weblinks/services/provider.php b/src/plugins/search/weblinks/services/provider.php
index 47f24db..1a7c075 100644
--- a/src/plugins/search/weblinks/services/provider.php
+++ b/src/plugins/search/weblinks/services/provider.php
@@ -8,7 +8,9 @@
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
-defined('_JEXEC') or die;
+// phpcs:disable PSR1.Files.SideEffects
+\defined('_JEXEC') or die;
+// phpcs:enable PSR1.Files.SideEffects
use Joomla\CMS\Extension\PluginInterface;
use Joomla\CMS\Factory;
@@ -20,31 +22,31 @@ use Joomla\Event\DispatcherInterface;
use Joomla\Plugin\Search\Weblinks\Extension\Weblinks;
return new class () implements ServiceProviderInterface {
- /**
- * Registers the service provider with a DI container.
- *
- * @param Container $container The DI container.
- *
- * @return void
- *
- * @since __DEPLOY_VERSION__
- */
- public function register(Container $container)
- {
- $container->set(
- PluginInterface::class,
- function (Container $container) {
- $app = Factory::getApplication();
- $dispatcher = $container->get(DispatcherInterface::class);
- $database = $container->get(DatabaseInterface::class);
+ /**
+ * Registers the service provider with a DI container.
+ *
+ * @param Container $container The DI container.
+ *
+ * @return void
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function register(Container $container)
+ {
+ $container->set(
+ PluginInterface::class,
+ function (Container $container) {
+ $app = Factory::getApplication();
+ $dispatcher = $container->get(DispatcherInterface::class);
+ $database = $container->get(DatabaseInterface::class);
- return new Weblinks(
- $dispatcher,
- (array) PluginHelper::getPlugin('finder', 'weblinks'),
- $app,
- $database
- );
- }
- );
- }
+ return new Weblinks(
+ $dispatcher,
+ (array) PluginHelper::getPlugin('finder', 'weblinks'),
+ $app,
+ $database
+ );
+ }
+ );
+ }
};
diff --git a/src/plugins/search/weblinks/src/Extension/Weblinks.php b/src/plugins/search/weblinks/src/Extension/Weblinks.php
index 5864c4d..a7a2812 100644
--- a/src/plugins/search/weblinks/src/Extension/Weblinks.php
+++ b/src/plugins/search/weblinks/src/Extension/Weblinks.php
@@ -1,4 +1,5 @@
setApplication($application);
- $this->setDatabase($database);
- }
+ $this->setApplication($application);
+ $this->setDatabase($database);
+ }
- /**
- * Determine areas searchable by this plugin.
- *
- * @return array An array of search areas.
- *
- * @since 1.6
- */
- public function onContentSearchAreas()
- {
- static $areas = [
- 'weblinks' => 'PLG_SEARCH_WEBLINKS_WEBLINKS',
- ];
+ /**
+ * Determine areas searchable by this plugin.
+ *
+ * @return array An array of search areas.
+ *
+ * @since 1.6
+ */
+ public function onContentSearchAreas()
+ {
+ static $areas = [
+ 'weblinks' => 'PLG_SEARCH_WEBLINKS_WEBLINKS',
+ ];
- return $areas;
- }
+ return $areas;
+ }
- /**
- * Search content (weblinks).
- *
- * The SQL must return the following fields that are used in a common display
- * routine: href, title, section, created, text, browsernav
- *
- * @param string $text Target search string.
- * @param string $phrase Matching option (possible values: exact|any|all). Default is "any".
- * @param string $ordering Ordering option (possible values: newest|oldest|popular|alpha|category). Default is "newest".
- * @param mixed $areas An array if the search it to be restricted to areas or null to search all areas.
- *
- * @return array Search results.
- *
- * @since 1.6
- */
- public function onContentSearch($text, $phrase = '', $ordering = '', $areas = null)
- {
- $app = $this->getApplication();
- $db = $this->getDatabase();
- $groups = $app->getIdentity()->getAuthorisedViewLevels();
+ /**
+ * Search content (weblinks).
+ *
+ * The SQL must return the following fields that are used in a common display
+ * routine: href, title, section, created, text, browsernav
+ *
+ * @param string $text Target search string.
+ * @param string $phrase Matching option (possible values: exact|any|all). Default is "any".
+ * @param string $ordering Ordering option (possible values: newest|oldest|popular|alpha|category). Default is "newest".
+ * @param mixed $areas An array if the search it to be restricted to areas or null to search all areas.
+ *
+ * @return array Search results.
+ *
+ * @since 1.6
+ */
+ public function onContentSearch($text, $phrase = '', $ordering = '', $areas = null)
+ {
+ $app = $this->getApplication();
+ $db = $this->getDatabase();
+ $groups = $app->getIdentity()->getAuthorisedViewLevels();
- $searchText = $text;
+ $searchText = $text;
- if (is_array($areas)
- && !array_intersect($areas, array_keys($this->onContentSearchAreas())))
- {
- return [];
- }
+ if (
+ is_array($areas)
+ && !array_intersect($areas, array_keys($this->onContentSearchAreas()))
+ ) {
+ return [];
+ }
- $sContent = $this->params->get('search_content', 1);
- $sArchived = $this->params->get('search_archived', 1);
- $limit = $this->params->def('search_limit', 50);
- $state = [];
+ $sContent = $this->params->get('search_content', 1);
+ $sArchived = $this->params->get('search_archived', 1);
+ $limit = $this->params->def('search_limit', 50);
+ $state = [];
- if ($sContent)
- {
- $state[] = 1;
- }
+ if ($sContent) {
+ $state[] = 1;
+ }
- if ($sArchived)
- {
- $state[] = 2;
- }
+ if ($sArchived) {
+ $state[] = 2;
+ }
- if (empty($state))
- {
- return [];
- }
+ if (empty($state)) {
+ return [];
+ }
- $text = trim($text);
+ $text = trim($text);
- if ($text == '')
- {
- return [];
- }
+ if ($text == '') {
+ return [];
+ }
- $searchWeblinks = Text::_('PLG_SEARCH_WEBLINKS');
+ $searchWeblinks = Text::_('PLG_SEARCH_WEBLINKS');
- switch ($phrase)
- {
- case 'exact':
- $text = $db->quote('%' . $db->escape($text, true) . '%', false);
- $wheres2 = [];
- $wheres2[] = 'a.url LIKE ' . $text;
- $wheres2[] = 'a.description LIKE ' . $text;
- $wheres2[] = 'a.title LIKE ' . $text;
- $where = '(' . implode(') OR (', $wheres2) . ')';
- break;
+ switch ($phrase) {
+ case 'exact':
+ $text = $db->quote('%' . $db->escape($text, true) . '%', false);
+ $wheres2 = [];
+ $wheres2[] = 'a.url LIKE ' . $text;
+ $wheres2[] = 'a.description LIKE ' . $text;
+ $wheres2[] = 'a.title LIKE ' . $text;
+ $where = '(' . implode(') OR (', $wheres2) . ')';
+ break;
- case 'all':
- case 'any':
- default:
- $words = explode(' ', $text);
- $wheres = [];
+ case 'all':
+ case 'any':
+ default:
+ $words = explode(' ', $text);
+ $wheres = [];
- foreach ($words as $word)
- {
- $word = $db->quote('%' . $db->escape($word, true) . '%', false);
- $wheres2 = [];
- $wheres2[] = 'a.url LIKE ' . $word;
- $wheres2[] = 'a.description LIKE ' . $word;
- $wheres2[] = 'a.title LIKE ' . $word;
- $wheres[] = implode(' OR ', $wheres2);
- }
+ foreach ($words as $word) {
+ $word = $db->quote('%' . $db->escape($word, true) . '%', false);
+ $wheres2 = [];
+ $wheres2[] = 'a.url LIKE ' . $word;
+ $wheres2[] = 'a.description LIKE ' . $word;
+ $wheres2[] = 'a.title LIKE ' . $word;
+ $wheres[] = implode(' OR ', $wheres2);
+ }
- $where = '(' . implode(($phrase == 'all' ? ') AND (' : ') OR ('), $wheres) . ')';
- break;
- }
+ $where = '(' . implode(($phrase == 'all' ? ') AND (' : ') OR ('), $wheres) . ')';
+ break;
+ }
- switch ($ordering)
- {
- case 'oldest':
- $order = 'a.created ASC';
- break;
+ switch ($ordering) {
+ case 'oldest':
+ $order = 'a.created ASC';
+ break;
- case 'popular':
- $order = 'a.hits DESC';
- break;
+ case 'popular':
+ $order = 'a.hits DESC';
+ break;
- case 'alpha':
- $order = 'a.title ASC';
- break;
+ case 'alpha':
+ $order = 'a.title ASC';
+ break;
- case 'category':
- $order = 'c.title ASC, a.title ASC';
- break;
+ case 'category':
+ $order = 'c.title ASC, a.title ASC';
+ break;
- case 'newest':
- default:
- $order = 'a.created DESC';
- }
+ case 'newest':
+ default:
+ $order = 'a.created DESC';
+ }
- $query = $db->getQuery(true);
+ $query = $db->getQuery(true);
- // SQLSRV changes.
- $caseWhen = ' CASE WHEN ';
- $caseWhen .= $query->charLength('a.alias', '!=', '0');
- $caseWhen .= ' THEN ';
- $a_id = $query->castAs('CHAR', 'a.id');
- $caseWhen .= $query->concatenate([$a_id, 'a.alias'], ':');
- $caseWhen .= ' ELSE ';
- $caseWhen .= $a_id . ' END as slug';
+ // SQLSRV changes.
+ $caseWhen = ' CASE WHEN ';
+ $caseWhen .= $query->charLength('a.alias', '!=', '0');
+ $caseWhen .= ' THEN ';
+ $a_id = $query->castAs('CHAR', 'a.id');
+ $caseWhen .= $query->concatenate([$a_id, 'a.alias'], ':');
+ $caseWhen .= ' ELSE ';
+ $caseWhen .= $a_id . ' END as slug';
- $caseWhen1 = ' CASE WHEN ';
- $caseWhen1 .= $query->charLength('c.alias', '!=', '0');
- $caseWhen1 .= ' THEN ';
- $c_id = $query->castAs('CHAR', 'c.id');
- $caseWhen1 .= $query->concatenate([$c_id, 'c.alias'], ':');
- $caseWhen1 .= ' ELSE ';
- $caseWhen1 .= $c_id . ' END as catslug';
+ $caseWhen1 = ' CASE WHEN ';
+ $caseWhen1 .= $query->charLength('c.alias', '!=', '0');
+ $caseWhen1 .= ' THEN ';
+ $c_id = $query->castAs('CHAR', 'c.id');
+ $caseWhen1 .= $query->concatenate([$c_id, 'c.alias'], ':');
+ $caseWhen1 .= ' ELSE ';
+ $caseWhen1 .= $c_id . ' END as catslug';
- $query->select('a.title AS title, a.created AS created, a.url, a.description AS text, ' . $caseWhen . "," . $caseWhen1)
- ->select($query->concatenate([$db->quote($searchWeblinks), 'c.title'], " / ") . ' AS section')
- ->select('\'1\' AS browsernav')
- ->from('#__weblinks AS a')
- ->join('INNER', '#__categories as c ON c.id = a.catid')
- ->where('(' . $where . ')')
- ->whereIn($db->quoteName('a.state'), $state)
- ->where($db->quoteName('c.published') . ' = 1')
- ->whereIn($db->quoteName('c.access'), $groups)
- ->order($order);
+ $query->select('a.title AS title, a.created AS created, a.url, a.description AS text, ' . $caseWhen . "," . $caseWhen1)
+ ->select($query->concatenate([$db->quote($searchWeblinks), 'c.title'], " / ") . ' AS section')
+ ->select('\'1\' AS browsernav')
+ ->from('#__weblinks AS a')
+ ->join('INNER', '#__categories as c ON c.id = a.catid')
+ ->where('(' . $where . ')')
+ ->whereIn($db->quoteName('a.state'), $state)
+ ->where($db->quoteName('c.published') . ' = 1')
+ ->whereIn($db->quoteName('c.access'), $groups)
+ ->order($order);
- // Filter by language.
+ // Filter by language.
- if ($app->isClient('site') && Multilanguage::isEnabled())
- {
- $languages = [$app->getLanguage()->getTag(), '*'];
- $query->whereIn($db->quoteName('a.language'), $languages, ParameterType::STRING)
- ->whereIn($db->quoteName('c.language'), $languages, ParameterType::STRING);
- }
+ if ($app->isClient('site') && Multilanguage::isEnabled()) {
+ $languages = [$app->getLanguage()->getTag(), '*'];
+ $query->whereIn($db->quoteName('a.language'), $languages, ParameterType::STRING)
+ ->whereIn($db->quoteName('c.language'), $languages, ParameterType::STRING);
+ }
- $db->setQuery($query, 0, $limit);
- $rows = $db->loadObjectList();
+ $db->setQuery($query, 0, $limit);
+ $rows = $db->loadObjectList();
- $return = [];
+ $return = [];
- if ($rows)
- {
- foreach ($rows as $key => $row)
- {
- $rows[$key]->href = RouteHelper::getWeblinkRoute($row->slug, $row->catslug);
- }
+ if ($rows) {
+ foreach ($rows as $key => $row) {
+ $rows[$key]->href = RouteHelper::getWeblinkRoute($row->slug, $row->catslug);
+ }
- foreach ($rows as $weblink)
- {
- if (\searchHelper::checkNoHTML($weblink, $searchText, ['url', 'text', 'title']))
- {
- $return[] = $weblink;
- }
- }
- }
+ foreach ($rows as $weblink) {
+ if (\searchHelper::checkNoHTML($weblink, $searchText, ['url', 'text', 'title'])) {
+ $return[] = $weblink;
+ }
+ }
+ }
- return $return;
- }
+ return $return;
+ }
}
diff --git a/src/plugins/system/weblinks/services/provider.php b/src/plugins/system/weblinks/services/provider.php
index 572b21f..6e2a7d3 100644
--- a/src/plugins/system/weblinks/services/provider.php
+++ b/src/plugins/system/weblinks/services/provider.php
@@ -8,7 +8,9 @@
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
-defined('_JEXEC') or die;
+// phpcs:disable PSR1.Files.SideEffects
+\defined('_JEXEC') or die;
+// phpcs:enable PSR1.Files.SideEffects
use Joomla\CMS\Extension\PluginInterface;
use Joomla\CMS\Plugin\PluginHelper;
@@ -19,29 +21,29 @@ use Joomla\Event\DispatcherInterface;
use Joomla\Plugin\System\Weblinks\Extension\Weblinks;
return new class () implements ServiceProviderInterface {
- /**
- * Registers the service provider with a DI container.
- *
- * @param Container $container The DI container.
- *
- * @return void
- *
- * @since __DEPLOY_VERSION__
- */
- public function register(Container $container)
- {
- $container->set(
- PluginInterface::class,
- function (Container $container) {
- $dispatcher = $container->get(DispatcherInterface::class);
- $database = $container->get(DatabaseInterface::class);
+ /**
+ * Registers the service provider with a DI container.
+ *
+ * @param Container $container The DI container.
+ *
+ * @return void
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function register(Container $container)
+ {
+ $container->set(
+ PluginInterface::class,
+ function (Container $container) {
+ $dispatcher = $container->get(DispatcherInterface::class);
+ $database = $container->get(DatabaseInterface::class);
- return new Weblinks(
- $dispatcher,
- (array) PluginHelper::getPlugin('system', 'weblinks'),
- $database
- );
- }
- );
- }
+ return new Weblinks(
+ $dispatcher,
+ (array) PluginHelper::getPlugin('system', 'weblinks'),
+ $database
+ );
+ }
+ );
+ }
};
diff --git a/src/plugins/system/weblinks/src/Extension/Weblinks.php b/src/plugins/system/weblinks/src/Extension/Weblinks.php
index e378804..ee7d19e 100644
--- a/src/plugins/system/weblinks/src/Extension/Weblinks.php
+++ b/src/plugins/system/weblinks/src/Extension/Weblinks.php
@@ -1,4 +1,5 @@
setDatabase($database);
- }
+ $this->setDatabase($database);
+ }
- /**
- * Returns an array of CMS events this plugin will listen to and the respective handlers.
- *
- * @return array
- *
- * @since __DEPLOY_VERSION__
- */
- public static function getSubscribedEvents(): array
- {
- return [
- 'onGetStats' => 'onGetStats',
- ];
- }
+ /**
+ * Returns an array of CMS events this plugin will listen to and the respective handlers.
+ *
+ * @return array
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public static function getSubscribedEvents(): array
+ {
+ return [
+ 'onGetStats' => 'onGetStats',
+ ];
+ }
- /**
- * Method to add statistics information to Administrator control panel.
- *
- * @param string $extension The extension requesting information.
- *
- * @return void
- *
- * @since __DEPLOY_VERSION__
- */
- public function onGetStats(Event $event)
- {
- if (!ComponentHelper::isEnabled('com_weblinks'))
- {
- return;
- }
+ /**
+ * Method to add statistics information to Administrator control panel.
+ *
+ * @param string $extension The extension requesting information.
+ *
+ * @return void
+ *
+ * @since __DEPLOY_VERSION__
+ */
+ public function onGetStats(Event $event)
+ {
+ if (!ComponentHelper::isEnabled('com_weblinks')) {
+ return;
+ }
- [$extension] = $event->getArguments();
+ [$extension] = $event->getArguments();
- if (!in_array($extension, $this->supportedExtensions))
- {
- return;
- }
+ if (!in_array($extension, $this->supportedExtensions)) {
+ return;
+ }
- $db = $this->getDatabase();
- $query = $db->getQuery(true)
- ->select('COUNT(id) AS count_links')
- ->from('#__weblinks')
- ->where('state = 1');
- $webLinks = $db->setQuery($query)->loadResult();
+ $db = $this->getDatabase();
+ $query = $db->getQuery(true)
+ ->select('COUNT(id) AS count_links')
+ ->from('#__weblinks')
+ ->where('state = 1');
+ $webLinks = $db->setQuery($query)->loadResult();
- if (!$webLinks)
- {
- return;
- }
+ if (!$webLinks) {
+ return;
+ }
- $result = $event->getArgument('result', []);
- $result[] = [
- [
- 'title' => Text::_('PLG_SYSTEM_WEBLINKS_STATISTICS'),
- 'icon' => 'out-2',
- 'data' => $webLinks,
- ],
- ];
+ $result = $event->getArgument('result', []);
+ $result[] = [
+ [
+ 'title' => Text::_('PLG_SYSTEM_WEBLINKS_STATISTICS'),
+ 'icon' => 'out-2',
+ 'data' => $webLinks,
+ ],
+ ];
- $event->setArgument('result', $result);
- }
+ $event->setArgument('result', $result);
+ }
}
diff --git a/tests/cypress/.eslinitrc.js b/tests/cypress/.eslinitrc.js
new file mode 100644
index 0000000..25e20e8
--- /dev/null
+++ b/tests/cypress/.eslinitrc.js
@@ -0,0 +1,12 @@
+module.exports = {
+ plugins: [
+ 'cypress',
+ ],
+ env: {
+ mocha: true,
+ 'cypress/globals': true,
+ },
+ rules: {
+ strict: 'off',
+ },
+};
diff --git a/tests/cypress/fixtures/.gitkeep b/tests/cypress/fixtures/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/tests/cypress/integration/install/install.cy.js b/tests/cypress/integration/install/install.cy.js
new file mode 100644
index 0000000..3884ad0
--- /dev/null
+++ b/tests/cypress/integration/install/install.cy.js
@@ -0,0 +1,11 @@
+// type definitions for Cypress object "cy"
+//
+
+describe('Install Joomla and Weblinks package', () => {
+ it('Install Joomla and Weblinks package', function () {
+ cy.doAdministratorLogin(Cypress.env('username'), Cypress.env('password'))
+ cy.disableStatistics()
+ cy.setErrorReportingToDevelopment()
+ cy.doAdministratorLogout()
+ })
+})
diff --git a/tests/cypress/plugins/.gitkeep b/tests/cypress/plugins/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/tests/cypress/plugins/index.js b/tests/cypress/plugins/index.js
new file mode 100644
index 0000000..e69de29
diff --git a/tests/cypress/support/commands.js b/tests/cypress/support/commands.js
new file mode 100644
index 0000000..c8381c1
--- /dev/null
+++ b/tests/cypress/support/commands.js
@@ -0,0 +1,129 @@
+Cypress.Commands.add('createContentCategory', (title) => {
+ cy.visit('administrator/index.php?option=com_categories&view=categories&extension=com_content')
+ cy.contains('h1', 'Articles: Categories').should('exist')
+ cy.clickToolbarButton('New')
+ cy.get('#jform_title').should('exist').type(title)
+ cy.clickToolbarButton('Save & Close')
+
+ // TODO Still need to implement this. Quick fix: we need to refactor the test
+ //$testCategory = [
+ // 'title' => $title,
+ // 'extension' => 'com_content',
+ //];
+
+ //$this->seeInDatabase('categories', $testCategory);
+
+})
+
+Cypress.Commands.add('createField', (type, title) => {
+ cy.visit('administrator/index.php?option=com_fields&view=fields&context=com_content.article')
+ cy.clickToolbarButton('New')
+ cy.get('#jform_title').type(title)
+ cy.get('#jform_type').select(type)
+ cy.clickToolbarButton('Save & Close')
+ cy.get('#system-message-container').contains('Field saved').should('exist')
+})
+
+Cypress.Commands.add('trashField', (title, message) => {
+ cy.visit('administrator/index.php?option=com_fields&view=fields&context=com_content.article')
+ cy.searchForItem(title)
+ cy.checkAllResults()
+ cy.clickToolbarButton('Action')
+ cy.clickToolbarButton('Trash')
+ cy.get('#system-message-container').contains(message).should('exist')
+})
+
+Cypress.Commands.add('deleteField', (title, message) => {
+ cy.visit('administrator/index.php?option=com_fields&view=fields&context=com_content.article')
+ cy.searchForItem()
+ cy.get('.js-stools-btn-filter').click()
+ cy.intercept('index.php*').as('setTrashed')
+ cy.get('#filter_state').select('Trashed')
+ cy.wait('@setTrashed')
+ cy.searchForItem(title)
+ cy.checkAllResults()
+ cy.clickToolbarButton('Empty trash')
+ cy.get('#system-message-container').contains(message).should('exist')
+})
+
+Cypress.Commands.add('createArticle', (articleDetails) => {
+ cy.visit('administrator/index.php?option=com_content&view=articles')
+ cy.intercept('index.php?option=com_content&view=article*').as('article_edit')
+ cy.clickToolbarButton('New')
+ cy.wait('@article_edit')
+ cy.get('#jform_title').clear().type(articleDetails.title)
+ cy.get('#jform_alias').clear().type(articleDetails.alias)
+ cy.intercept('index.php?option=com_content&view=articles').as('article_list')
+ cy.clickToolbarButton('Save & Close')
+ cy.wait('@article_list')
+ cy.get('#system-message-container').contains('Article saved.').should('exist')
+})
+
+Cypress.Commands.add('featureArticle', (title) => {
+ cy.visit('administrator/index.php?option=com_content&view=articles')
+ cy.searchForItem(title)
+ cy.checkAllResults()
+ cy.clickToolbarButton('Action')
+ cy.intercept('index.php?option=com_content&view=articles').as('article_feature')
+ cy.clickToolbarButton('feature')
+ cy.wait('@article_feature')
+ cy.get('#system-message-container').contains('Article featured.').should('exist')
+})
+
+Cypress.Commands.add('setArticleAccessLevel', (title, accessLevel) => {
+ cy.visit('administrator/index.php?option=com_content&view=articles')
+ cy.searchForItem(title)
+ cy.checkAllResults()
+ cy.intercept('index.php?option=com_content&view=article*').as('article_access')
+ cy.get('a').contains(title).click()
+ cy.wait('@article_access')
+ cy.get('#jform_access').select(accessLevel)
+ cy.intercept('index.php?option=com_content&view=article*').as('article_list')
+ cy.clickToolbarButton('Save & Close')
+ cy.wait('@article_list')
+ cy.get('td').contains(accessLevel).should('exist')
+})
+
+Cypress.Commands.add('unPublishArticle', (title) => {
+ cy.visit('administrator/index.php?option=com_content&view=articles')
+ cy.searchForItem(title)
+ cy.checkAllResults()
+ cy.clickToolbarButton('Action')
+ cy.intercept('index.php?option=com_content&view=articles').as('article_unpublish')
+ cy.clickToolbarButton('unpublish')
+ cy.wait('@article_unpublish')
+})
+
+Cypress.Commands.add('publishArticle', (title) => {
+ cy.visit('administrator/index.php?option=com_content&view=articles')
+ cy.searchForItem(title)
+ cy.checkAllResults()
+ cy.clickToolbarButton('Action')
+ cy.intercept('index.php?option=com_content&view=articles').as('article_publish')
+ cy.clickToolbarButton('publish')
+ cy.wait('@article_publish')
+})
+
+Cypress.Commands.add('trashArticle', (title) => {
+ cy.visit('administrator/index.php?option=com_content&view=articles')
+ cy.searchForItem(title)
+ cy.checkAllResults()
+ cy.clickToolbarButton('Action')
+ cy.intercept('index.php?option=com_content&view=articles').as('article_trash')
+ cy.clickToolbarButton('trash')
+ cy.wait('@article_trash')
+})
+
+Cypress.Commands.add('deleteArticle', (title) => {
+ cy.visit('administrator/index.php?option=com_content&view=articles')
+ cy.setFilter('published', 'Trashed')
+ cy.searchForItem(title)
+ cy.checkAllResults()
+ cy.on("window:confirm", (s) => {
+ return true;
+ });
+ cy.intercept('index.php?option=com_content&view=articles').as('article_delete')
+ cy.clickToolbarButton('empty trash');
+ cy.wait('@article_delete')
+ cy.wait('@article_delete')
+})
diff --git a/tests/cypress/support/index.js b/tests/cypress/support/index.js
new file mode 100644
index 0000000..a12bdc6
--- /dev/null
+++ b/tests/cypress/support/index.js
@@ -0,0 +1,34 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+import 'joomla-cypress'
+
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
+
+before(function() {
+ const {registerCommands} = require('../../../node_modules/joomla-cypress/src/index.js')
+
+ registerCommands()
+
+ Cypress.on('uncaught:exception', (err, runnable) => {
+ console.log("err :" + err)
+ console.log("runnable :" + runnable)
+ return false
+ })
+})
diff --git a/tests/travis-ci-apache.conf b/tests/travis-ci-apache.conf
deleted file mode 100644
index 40af5c6..0000000
--- a/tests/travis-ci-apache.conf
+++ /dev/null
@@ -1,26 +0,0 @@
-
- ServerAdmin webmaster@localhost
- DocumentRoot %TRAVIS_BUILD_DIR%
-
-
- Options FollowSymLinks
- AllowOverride All
-
-
-
- Options FollowSymLinks MultiViews ExecCGI
- AllowOverride All
- Order deny,allow
- Allow from all
-
-
- # Wire up Apache to use Travis CI's php-fpm.
-
- AddHandler php%PHPVERSION%-fcgi .php
- Action php%PHPVERSION%-fcgi /php%PHPVERSION%-fcgi
- Alias /php%PHPVERSION%-fcgi /usr/lib/cgi-bin/php%PHPVERSION%-fcgi
- FastCgiExternalServer /usr/lib/cgi-bin/php%PHPVERSION%-fcgi -socket /tmp/php%PHPVERSION%-fpm.sock -pass-header Authorization
-
-
- ErrorLog ${APACHE_LOG_DIR}/error.log
-
diff --git a/tests/travis-php-fpm.sh b/tests/travis-php-fpm.sh
deleted file mode 100644
index 13f7c11..0000000
--- a/tests/travis-php-fpm.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-
-owner="$1"
-phpversionname="$2"
-
-file="/home/$owner/.phpenv/versions/$phpversionname/etc/php-fpm.conf"
-
-cp /home/$owner/.phpenv/versions/$phpversionname/etc/php-fpm.conf.default /home/$owner/.phpenv/versions/$phpversionname/etc/php-fpm.conf
-if [ -f /home/$owner/.phpenv/versions/$phpversionname/etc/php-fpm.d/www.conf.default ]; then
- cp /home/$owner/.phpenv/versions/$phpversionname/etc/php-fpm.d/www.conf.default /home/$owner/.phpenv/versions/$phpversionname/etc/php-fpm.d/www.conf
- file=/home/$owner/.phpenv/versions/$phpversionname/etc/php-fpm.d/www.conf
-fi;
-
-sed -e "s,listen = 127.0.0.1:9000,listen = /tmp/php${phpversionname:0:1}-fpm.sock,g" --in-place $file
-sed -e "s,;listen.owner = nobody,listen.owner = $owner,g" --in-place $file
-sed -e "s,;listen.group = nobody,listen.group = $owner,g" --in-place $file
-sed -e "s,;listen.mode = 0660,listen.mode = 0666,g" --in-place $file
-sed -e "s,user = nobody,;user = $owner,g" --in-place $file
-sed -e "s,group = nobody,;group = $owner,g" --in-place $file