diff --git a/.circleci/config.yml b/.circleci/config.yml index ff4584da9f..0df0750369 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -30,7 +30,7 @@ commands: echo "git checkout << parameters.envname >>" echo "git fetch --all --tags" echo "git pull" - echo bin/deploy/git-annotated-tag-creator.sh << parameters.envname >> << pipeline.number >> $CMS_DIGEST $WAF_DIGEST + echo bin/deploy/git-annotated-tag-creator.sh << parameters.envname >> << pipeline.number >> $CMS_DIGEST $WAF_DIGEST $WWW_DIGEST echo fi - run: diff --git a/.docker/Dockerfile-cms b/.docker/Dockerfile-cms index 71f3553be4..bcc34b7e95 100644 --- a/.docker/Dockerfile-cms +++ b/.docker/Dockerfile-cms @@ -71,7 +71,7 @@ RUN COMPOSER_MEMORY_LIMIT=-1 composer install --ignore-platform-reqs --no-intera # USER www-data ############################################################### -FROM node:20.10-bullseye-slim AS theme-builder +FROM node:20-bullseye-slim AS theme-builder ARG BUID=1000 ARG BGID=1000 @@ -104,7 +104,7 @@ RUN npm install --production=false --prefix /var/www/web/themes/custom/usagov \ && chown -R node:node /var/www/web/themes ############################################################### -FROM alpine:3.18 AS cms +FROM alpine:3.20 AS cms ARG S6_VERSION ENV S6_VERSION ${S6_VERSION:-v2.2.0.3} @@ -153,54 +153,54 @@ RUN sed -E -i "s/:x:${BUID}:/:x:1919:/g" /etc/passwd \ mariadb-connector-c \ nginx \ nginx-mod-http-lua \ - php81 \ - php81-fpm \ - php81-bcmath \ - php81-bz2 \ - php81-calendar \ - php81-curl \ - php81-ctype \ - php81-dom \ - php81-fileinfo \ - php81-ftp \ - php81-gd \ - php81-intl \ - php81-iconv \ - php81-imap \ - php81-intl \ - php81-json \ - php81-ldap \ - php81-mbstring \ - php81-mysqlnd \ - php81-openssl \ - php81-opcache \ - php81-pcntl \ - php81-pdo \ - php81-pdo_mysql \ - php81-pdo_sqlite \ - php81-pear \ - php81-pecl-imagick \ - php81-pecl-xdebug \ - php81-phar \ - php81-posix \ - php81-session \ - php81-simplexml \ - php81-shmop \ - php81-soap \ - php81-sockets \ - php81-sodium \ - php81-sqlite3 \ - php81-sysvmsg \ - php81-sysvsem \ - php81-sysvshm \ - php81-tokenizer \ - php81-tidy \ - php81-xsl \ - php81-xml \ - php81-xmlreader \ - php81-xmlwriter \ - php81-zip \ - php81-zlib \ + php83 \ + php83-fpm \ + php83-bcmath \ + php83-bz2 \ + php83-calendar \ + php83-curl \ + php83-ctype \ + php83-dom \ + php83-fileinfo \ + php83-ftp \ + php83-gd \ + php83-intl \ + php83-iconv \ + php83-imap \ + php83-intl \ + php83-json \ + php83-ldap \ + php83-mbstring \ + php83-mysqlnd \ + php83-openssl \ + php83-opcache \ + php83-pcntl \ + php83-pdo \ + php83-pdo_mysql \ + php83-pdo_sqlite \ + php83-pear \ + php83-pecl-imagick \ + php83-pecl-xdebug \ + php83-phar \ + php83-posix \ + php83-session \ + php83-simplexml \ + php83-shmop \ + php83-soap \ + php83-sockets \ + php83-sodium \ + php83-sqlite3 \ + php83-sysvmsg \ + php83-sysvsem \ + php83-sysvshm \ + php83-tokenizer \ + php83-tidy \ + php83-xsl \ + php83-xml \ + php83-xmlreader \ + php83-xmlwriter \ + php83-zip \ + php83-zlib \ && mkdir -p /var/www/web/sites/default/files \ # s6 supervisor setup && tar xzf /tmp/s6overlay.tar.gz -C / \ @@ -217,7 +217,7 @@ RUN sed -E -i "s/:x:${BUID}:/:x:1919:/g" /etc/passwd \ && mkdir -p /run/nginx/ \ && touch /run/nginx/nginx.pid \ # php setup - && ln -s /usr/sbin/php-fpm81 /usr/sbin/php-fpm + && ln -s /usr/sbin/php-fpm83 /usr/sbin/php-fpm # new relic setup COPY bin/src/newrelic.sh /local/newrelic.sh diff --git a/.docker/Dockerfile-www b/.docker/Dockerfile-www index 034983f705..2657de7838 100644 --- a/.docker/Dockerfile-www +++ b/.docker/Dockerfile-www @@ -1,6 +1,6 @@ ############################################################### -FROM alpine:3.18 AS www +FROM alpine:3.20 AS www ARG S6_VERSION ENV S6_VERSION ${S6_VERSION:-v2.2.0.3} @@ -49,54 +49,54 @@ RUN sed -E -i "s/:x:${BUID}:/:x:1919:/g" /etc/passwd \ mariadb-connector-c \ nginx \ nginx-mod-http-lua \ - php81 \ -# php81-fpm \ - php81-bcmath \ - php81-bz2 \ - php81-calendar \ - php81-curl \ - php81-ctype \ - php81-dom \ - php81-fileinfo \ - php81-ftp \ - php81-gd \ - php81-intl \ - php81-iconv \ - php81-imap \ - php81-intl \ - php81-json \ - php81-ldap \ - php81-mbstring \ - php81-mysqlnd \ - php81-openssl \ - php81-opcache \ - php81-pcntl \ - php81-pdo \ - php81-pdo_mysql \ - php81-pdo_sqlite \ - php81-pear \ - php81-pecl-imagick \ - php81-pecl-xdebug \ - php81-phar \ - php81-posix \ - php81-session \ - php81-simplexml \ - php81-shmop \ - php81-soap \ - php81-sockets \ - php81-sodium \ - php81-sqlite3 \ - php81-sysvmsg \ - php81-sysvsem \ - php81-sysvshm \ - php81-tokenizer \ - php81-tidy \ - php81-xsl \ - php81-xml \ - php81-xmlreader \ - php81-xmlwriter \ - php81-zip \ - php81-zlib \ + php83 \ +# php83-fpm \ + php83-bcmath \ + php83-bz2 \ + php83-calendar \ + php83-curl \ + php83-ctype \ + php83-dom \ + php83-fileinfo \ + php83-ftp \ + php83-gd \ + php83-intl \ + php83-iconv \ + php83-imap \ + php83-intl \ + php83-json \ + php83-ldap \ + php83-mbstring \ + php83-mysqlnd \ + php83-openssl \ + php83-opcache \ + php83-pcntl \ + php83-pdo \ + php83-pdo_mysql \ + php83-pdo_sqlite \ + php83-pear \ + php83-pecl-imagick \ + php83-pecl-xdebug \ + php83-phar \ + php83-posix \ + php83-session \ + php83-simplexml \ + php83-shmop \ + php83-soap \ + php83-sockets \ + php83-sodium \ + php83-sqlite3 \ + php83-sysvmsg \ + php83-sysvsem \ + php83-sysvshm \ + php83-tokenizer \ + php83-tidy \ + php83-xsl \ + php83-xml \ + php83-xmlreader \ + php83-xmlwriter \ + php83-zip \ + php83-zlib \ && mkdir -p /var/www/web/sites/default/files \ # s6 supervisor setup && tar xzf /tmp/s6overlay.tar.gz -C / \ @@ -111,10 +111,10 @@ RUN sed -E -i "s/:x:${BUID}:/:x:1919:/g" /etc/passwd \ && ln -s /dev/stderr /var/log/nginx/error.log \ && ln -s /dev/stdout /var/log/nginx/access.log \ && mkdir -p /run/nginx/ \ - && touch /run/nginx/nginx.pid + && touch /run/nginx/nginx.pid # \ # php setup - #&& ln -s /usr/sbin/php-fpm81 /usr/sbin/php-fpm + #&& ln -s /usr/sbin/php-fpm83 /usr/sbin/php-fpm # new relic setup COPY bin/src/newrelic.sh /local/newrelic.sh diff --git a/.docker/src-cms/50_xdebug.ini b/.docker/src-cms/50_xdebug.ini index 9a91002363..eaf42534f9 100644 --- a/.docker/src-cms/50_xdebug.ini +++ b/.docker/src-cms/50_xdebug.ini @@ -4,3 +4,4 @@ xdebug.client_host=host.docker.internal xdebug.idekey=VSCODE xdebug.max_nesting_level=1500 xdebug.mode=debug +# xdebug.start_with_request=1 \ No newline at end of file diff --git a/.docker/src-cms/etc/nginx/partials/drupal.conf.tmpl b/.docker/src-cms/etc/nginx/partials/drupal.conf.tmpl index b1f1cb2a79..8150dacb2e 100755 --- a/.docker/src-cms/etc/nginx/partials/drupal.conf.tmpl +++ b/.docker/src-cms/etc/nginx/partials/drupal.conf.tmpl @@ -79,19 +79,6 @@ } location / { - # Decode the URI for proper matching - set $decoded_uri $uri; - # We will react on URLs ending with spaces, non-breaking spaces, thin-space, and Em-space - if ($decoded_uri ~* ^(.+?)(%C2%A0|\xA0|%E2%80%89|\xE2\x80\x89|%E2%80%83|\xE2\x80\x83)+$) { - set $clean_uri $1; - return 301 $clean_uri; - } - # Match and strip other partial %C2 sequences from the end of the URI - if ($uri ~* ^(.+?)(%C2|\xC2)+$) { - set $clean_uri $1; - return 301 $clean_uri; - } - # try_files $uri @rewrite; # For Drupal <= 6 try_files $uri /index.php?$query_string; # For Drupal >= 7 } diff --git a/.docker/src-cms/etc/php81/auto_prepend.php b/.docker/src-cms/etc/php83/auto_prepend.php similarity index 100% rename from .docker/src-cms/etc/php81/auto_prepend.php rename to .docker/src-cms/etc/php83/auto_prepend.php diff --git a/.docker/src-cms/etc/php81/php-fpm.conf b/.docker/src-cms/etc/php83/php-fpm.conf similarity index 86% rename from .docker/src-cms/etc/php81/php-fpm.conf rename to .docker/src-cms/etc/php83/php-fpm.conf index c4afcb7fe7..779181a07c 100755 --- a/.docker/src-cms/etc/php81/php-fpm.conf +++ b/.docker/src-cms/etc/php83/php-fpm.conf @@ -13,4 +13,4 @@ daemonize = no events.mechanism = epoll -include=/etc/php81/php-fpm.d/*.conf +include=/etc/php83/php-fpm.d/*.conf diff --git a/.docker/src-cms/etc/php81/php-fpm.d/env.conf.tmpl b/.docker/src-cms/etc/php83/php-fpm.d/env.conf.tmpl similarity index 100% rename from .docker/src-cms/etc/php81/php-fpm.d/env.conf.tmpl rename to .docker/src-cms/etc/php83/php-fpm.d/env.conf.tmpl diff --git a/.docker/src-cms/etc/php81/php-fpm.d/www.conf b/.docker/src-cms/etc/php83/php-fpm.d/www.conf similarity index 100% rename from .docker/src-cms/etc/php81/php-fpm.d/www.conf rename to .docker/src-cms/etc/php83/php-fpm.d/www.conf diff --git a/.docker/src-cms/etc/php81/php.ini b/.docker/src-cms/etc/php83/php.ini similarity index 97% rename from .docker/src-cms/etc/php81/php.ini rename to .docker/src-cms/etc/php83/php.ini index ecc31d2194..e8aa0fd3f7 100755 --- a/.docker/src-cms/etc/php81/php.ini +++ b/.docker/src-cms/etc/php83/php.ini @@ -29,7 +29,7 @@ report_memleaks = On track_errors = Off html_errors = On -auto_prepend_file = /etc/php81/auto_prepend.php +auto_prepend_file = /etc/php83/auto_prepend.php auto_append_file = default_mimetype = "text/html" diff --git a/.docker/src-waf/etc/nginx/conf.d/default.conf b/.docker/src-waf/etc/nginx/conf.d/default.conf index cb8db574b2..f0a8386692 100644 --- a/.docker/src-waf/etc/nginx/conf.d/default.conf +++ b/.docker/src-waf/etc/nginx/conf.d/default.conf @@ -215,10 +215,6 @@ server { if ($http_x_usa_forwarded_host ~* ^(www\.)?govloans\.gov$) { set $HostMatchFail "matched"; } - # gsa.benefits.gov is for testing; we can remove it after cutover - if ($http_x_usa_forwarded_host ~* ^gsa\.benefits\.gov$) { - set $HostMatchFail "matched"; - } if ($HostMatchFail = "NOMATCH") { # didn't match expected host; redirect to home page. diff --git a/.docker/src-waf/etc/nginx/snippets/domain-redirects.conf b/.docker/src-waf/etc/nginx/snippets/domain-redirects.conf index 0e2eb2202e..2303932deb 100644 --- a/.docker/src-waf/etc/nginx/snippets/domain-redirects.conf +++ b/.docker/src-waf/etc/nginx/snippets/domain-redirects.conf @@ -153,12 +153,6 @@ break; } - ## gsa.benefits.gov is for testing of the benefits rewrites and can be removed after cutover: - if ($cf_forwarded_host ~* ^gsa\.benefits\.gov$) { - set $port 8889; - break; - } - ## govloans.gov (part of the benefits.gov transition) if ($cf_forwarded_host ~* ^(www\.)?govloans\.gov$) { set $port 8889; diff --git a/.docker/src-www/etc/nginx/partials/staticsite.conf.tmpl b/.docker/src-www/etc/nginx/partials/staticsite.conf.tmpl index f14d6552c5..6efdea00e0 100644 --- a/.docker/src-www/etc/nginx/partials/staticsite.conf.tmpl +++ b/.docker/src-www/etc/nginx/partials/staticsite.conf.tmpl @@ -1,18 +1,4 @@ - location / { - # Decode the URI for proper matching - set $decoded_uri $uri; - if ($decoded_uri ~* ^(.+?)(%C2%A0|\xA0|%E2%80%89|\xE2\x80\x89|%E2%80%83|\xE2\x80\x83)+$) { - set $clean_uri $1; - return 301 $clean_uri; - } - # Match and strip other partial %C2 sequences from the end of the URI - if ($uri ~* ^(.+?)(%C2|\xC2)+$) { - set $clean_uri $1; - return 301 $clean_uri; - } - } - # spanish main url - easier as a separate case vs in another regex location ~* ^/(es)$ { error_page 404 @notFoundSpanish; diff --git a/README.md b/README.md index 11890913c2..1edf9ff9e4 100644 --- a/README.md +++ b/README.md @@ -174,7 +174,7 @@ To access the Drupal Portal to make any additional configurations, you will need Log out as root, and log in with your own user account. -**Note:** You will need to repeat these steps any time you re-load the database from a backup. +**Note:** You will need to repeat these steps any time you re-load the database from a backup. ### Automated tests setup (cypress) @@ -183,12 +183,12 @@ We use [Cypress](cypress.io). Note that we use only the Cypress App, _not_ Cypre * Tests run in the `cypress` Docker container. * The tests themselves are in the `automated_tests/e2e-cypress` directory. -* Twig debugging will break some of the tests! Turn it off before running tests to get the most accurate results. +* Twig debugging will break some of the tests! Turn it off before running tests to get the most accurate results. ## Minimal setup for headless tests -1. Supply Drupal *credentials* for the automated tests: Edit the file `env.local.cypress`. Supply a valid Drupal user name and password for `cypressCmsUser` and `cypressCmsPass`. +1. Supply Drupal *credentials* for the automated tests: Edit the file `env.local.cypress`. Supply a valid Drupal user name and password for `cypressCmsUser` and `cypressCmsPass`. 2. Run `docker compose up` to (re-)create the cypress container with the new environment variables. @@ -196,7 +196,7 @@ We use [Cypress](cypress.io). Note that we use only the Cypress App, _not_ Cypre You can run `npx cypress run --spec cypress/e2e` to run the entire test suite, or specify a smaller subset like `cypress/e2e/functional`. - The **Report** will be written to automated_tests/e2e-cypress/cypress/reports/html/index.html and you can open it in your web browser by navigating to that file and opening it. Cypress will report that it wrote the tests to /app/e2e-cypress/cypress/reports/html/index.html, which is the location of that file in the volume mounted to the cypress docker container. + The **Report** will be written to automated_tests/e2e-cypress/cypress/reports/html/index.html and you can open it in your web browser by navigating to that file and opening it. Cypress will report that it wrote the tests to /app/e2e-cypress/cypress/reports/html/index.html, which is the location of that file in the volume mounted to the cypress docker container. Note: The first time you run bin/init, it will create the `env.local.cypress` file by copying `env.default.cypress`. The default `cypressBaseUrl` in that file should be correct for running tests against your local dev site. @@ -232,7 +232,7 @@ This assumes you're using homebrew. The "network client" you're enabling this for is the virtual machine running in your cypress container. -4. Reboot your computer. (You need to reboot once after installing XQuartz. Thereafter, when you change your XQuartz settings you need to restart XQuartz, but not reboot.) +4. Reboot your computer. (You need to reboot once after installing XQuartz. Thereafter, when you change your XQuartz settings you need to restart XQuartz, but not reboot.) Proceed to [Allow cypress to open an X window](#allow-cypress-to-open-an-x-window) @@ -320,6 +320,22 @@ If you make any changes to the `scss` or `js` files, make sure to check for lint [back to top](#usagov-2021) +## Checking PHP Code style and syntax errors + +PHPCodesniffer and the parallel linting tools should be installed automatically on a local environment via `composer install`. PHPCodeSniffer is used to ensure new code follows Drupal's coding standard. The parallel linter will check for PHP syntax errors. If they detect any errors, they must be fixed before a PR of changes can be accepted. + +The following composer scripts are aliases for running these tools. + +* Check for code style errors across all project files. Must have zero errors: + `./bin/composer phpcs-errors`: +* Check for code style errors and warnings across all project files. + `./bin/composer phpcs-strict` +* Check for code style errors in current branch. Must have zero errors: + `./bin/composer phpcs-changes` +* Check for code style errors and warnings in current branch. + `./bin/composer phpcs-changes-strict` +* Check for PHP lint errors + `./bin/composer php-lint` ## Project Restart/Reset Sometimes, Docker problems arise after an upgrade and a more complete restart is needed. After closing down and destroying the existing containers, networks, and volumes the procedure is the same as the full project setup. diff --git a/automated_tests/cypress_build/package-lock.json b/automated_tests/cypress_build/package-lock.json index 8f0633f9f9..2205bca6c3 100644 --- a/automated_tests/cypress_build/package-lock.json +++ b/automated_tests/cypress_build/package-lock.json @@ -637,9 +637,9 @@ "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" }, "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==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", diff --git a/bin/changed-files b/bin/changed-files new file mode 100755 index 0000000000..5c39395093 --- /dev/null +++ b/bin/changed-files @@ -0,0 +1,9 @@ +#!/bin/bash + +CURRENT_BRANCH=`git branch --show-current` +# Get the changes between current branch and dev +CHANGED=`git diff --name-only --diff-filter=ARM dev $CURRENT_BRANCH` + +if [ "$CURRENT_BRANCH" != "dev" ]; then + echo $CHANGED; +fi diff --git a/bin/composer-reqs b/bin/composer-reqs new file mode 100755 index 0000000000..aa4fc8c6a8 --- /dev/null +++ b/bin/composer-reqs @@ -0,0 +1,9 @@ +#!/bin/bash +set -e + +docker compose run \ + --rm \ + --no-deps \ + --workdir /var/www \ + composer \ + composer "$@" diff --git a/bin/deploy/git-annotated-tag-creator.sh b/bin/deploy/git-annotated-tag-creator.sh index c9bbb7e578..76e3c9368d 100755 --- a/bin/deploy/git-annotated-tag-creator.sh +++ b/bin/deploy/git-annotated-tag-creator.sh @@ -53,7 +53,7 @@ assertIsImageDigest $WWW_DIGEST shift if [ $CMS_DIGEST = $WAF_DIGEST -o $CMS_DIGEST = $WWW_DIGEST ]; then - echo "Cannot use the same digest for any of the CMS, WAF and WWW images!" + echo "Cannot use the same digest for any of the CMS, WAF or WWW images - please check the arguments that were passed" exit 1 fi diff --git a/bin/deploy/git-annotation-parser.sh b/bin/deploy/git-annotation-parser.sh index 3a34a1d07e..17c5778827 100755 --- a/bin/deploy/git-annotation-parser.sh +++ b/bin/deploy/git-annotation-parser.sh @@ -21,16 +21,13 @@ else exit 1 fi -# just testing? -if [ x$1 == x"--dryrun" ]; then - export echo=echo - shift -fi - -SPACE=${1:-please-provide-space-as-first-argument} -SSPACE=$(echo "$SPACE" | tr '[:upper:]' '[:lower:]') ## lowercase, so tags are properly formatted -#assertCurSpace "$SPACE" ### <-- no need to assert that we're actually in $SPACE, because we're not doing anything w/ CF - just git +SPACE=$1 +if [ -z "$SPACE" ]; then + echo "First argument must be a valid CF space name" + exit 1 +fi; shift +SSPACE=$(echo "$SPACE" | tr '[:upper:]' '[:lower:]') ## lowercase, so tags are properly formatted # 1. Find the name of the latest annotated git tag matching our production post-deployment tag format # 2. Query the content field of the reference attached to the tag, and make sure it contains correctly formated build number and digest hashes @@ -157,7 +154,7 @@ if [ -n $ANNOTATED_TAG ]; then echo echo " ROUTE_SERVICE_APP_NAME=waf \\ ROUTE_SERVICE_NAME=waf-route-${SPACE}-usagov \\ - PROTECTED_APP_NAME=cms \\ + PROTECTED_APP_NAMES=cms \\ bin/cloudgov/deploy-waf $CCI_BUILD $WAF_DIGEST" echo echo diff --git a/bin/src/newrelic.sh b/bin/src/newrelic.sh index 4f7ed5a00f..28d0dac447 100755 --- a/bin/src/newrelic.sh +++ b/bin/src/newrelic.sh @@ -29,7 +29,7 @@ if [ "$(uname -m)" != 'aarch64' ]; then -e 's/;\?newrelic.loglevel =.*/newrelic.loglevel = "info"/' \ -e 's/;\?newrelic.enabled =.*/newrelic.enabled = false/' \ -e 's/;\?newrelic.error_collector.record_database_errors =.*/newrelic.error_collector.record_database_errors = true/' \ - /etc/php81/conf.d/newrelic.ini + /etc/php83/conf.d/newrelic.ini NR_LATEST_VERSION="$(curl -sS https://download.newrelic.com/php_agent/release/ | sed -n 's/.*>\(.*linux\-musl\).tar.gz<.*/\1/p')" export NR_LATEST_VERSION diff --git a/composer.json b/composer.json index c691cb717f..e16e6a0886 100644 --- a/composer.json +++ b/composer.json @@ -164,5 +164,29 @@ "drupal/ckeditor_templates" ] } + }, + "require-dev": { + "drupal/coder": "^8.3", + "php-parallel-lint/php-parallel-lint": "^1.4" + }, + "scripts": { + "changed-files": [ + "bin/changed-files" + ], + "phpcs-errors": [ + "vendor/bin/phpcs -n --standard=.phpcs.xml.dist" + ], + "phpcs-strict": [ + "vendor/bin/phpcs --standard=.phpcs.xml.dist" + ], + "phpcs-changes": [ + "vendor/bin/phpcs -n --standard=.phpcs.xml.dist `bin/changed-files`" + ], + "phpcs-changes-strict": [ + "vendor/bin/phpcs --standard=.phpcs.xml.dist `bin/changed-files`" + ], + "php-lint": [ + "vendor/bin/parallel-lint -e php,module,inc,install,test,profile,theme ./web/modules/custom ./web/themes/custom" + ] } } diff --git a/composer.lock b/composer.lock index 26b42f865d..8cf213b5e2 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": "93324a928ad5a44abbc3c4ab0c967cd6", + "content-hash": "750e25aca453a5fccca5ae752bbcd6e3", "packages": [ { "name": "asm89/stack-cors", @@ -118,16 +118,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.324.13", + "version": "3.334.3", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "781cb9594f7d1754c888452f980748115fd159d3" + "reference": "6576a9fcfc6ae7c76aed3c6fa4c3864060f72d04" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/781cb9594f7d1754c888452f980748115fd159d3", - "reference": "781cb9594f7d1754c888452f980748115fd159d3", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/6576a9fcfc6ae7c76aed3c6fa4c3864060f72d04", + "reference": "6576a9fcfc6ae7c76aed3c6fa4c3864060f72d04", "shasum": "" }, "require": { @@ -156,8 +156,8 @@ "nette/neon": "^2.3", "paragonie/random_compat": ">= 2", "phpunit/phpunit": "^5.6.3 || ^8.5 || ^9.5", - "psr/cache": "^1.0", - "psr/simple-cache": "^1.0", + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "psr/simple-cache": "^1.0 || ^2.0 || ^3.0", "sebastian/comparator": "^1.2.3 || ^4.0", "yoast/phpunit-polyfills": "^1.0" }, @@ -210,9 +210,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.324.13" + "source": "https://github.com/aws/aws-sdk-php/tree/3.334.3" }, - "time": "2024-10-29T18:11:10+00:00" + "time": "2024-12-10T19:41:55+00:00" }, { "name": "caxy/php-htmldiff", @@ -1525,29 +1525,27 @@ }, { "name": "doctrine/deprecations", - "version": "1.1.3", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" + "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", - "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/31610dbb31faa98e6b5447b62340826f54fbc4e9", + "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9", - "phpstan/phpstan": "1.4.10 || 1.10.15", - "phpstan/phpstan-phpunit": "^1.0", + "doctrine/coding-standard": "^9 || ^12", + "phpstan/phpstan": "1.4.10 || 2.0.3", + "phpstan/phpstan-phpunit": "^1.0 || ^2", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psalm/plugin-phpunit": "0.18.4", - "psr/log": "^1 || ^2 || ^3", - "vimeo/psalm": "4.30.0 || 5.12.0" + "psr/log": "^1 || ^2 || ^3" }, "suggest": { "psr/log": "Allows logging deprecations via PSR-3 logger implementation" @@ -1555,7 +1553,7 @@ "type": "library", "autoload": { "psr-4": { - "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + "Doctrine\\Deprecations\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1566,9 +1564,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.3" + "source": "https://github.com/doctrine/deprecations/tree/1.1.4" }, - "time": "2024-01-30T19:34:25+00:00" + "time": "2024-12-07T21:18:45+00:00" }, { "name": "doctrine/event-manager", @@ -1741,16 +1739,16 @@ }, { "name": "doctrine/persistence", - "version": "3.3.3", + "version": "3.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "b337726451f5d530df338fc7f68dee8781b49779" + "reference": "0ea965320cec355dba75031c1b23d4c78362e3ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/b337726451f5d530df338fc7f68dee8781b49779", - "reference": "b337726451f5d530df338fc7f68dee8781b49779", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/0ea965320cec355dba75031c1b23d4c78362e3ff", + "reference": "0ea965320cec355dba75031c1b23d4c78362e3ff", "shasum": "" }, "require": { @@ -1764,12 +1762,11 @@ "require-dev": { "doctrine/coding-standard": "^12", "doctrine/common": "^3.0", - "phpstan/phpstan": "1.11.1", + "phpstan/phpstan": "1.12.7", "phpstan/phpstan-phpunit": "^1", "phpstan/phpstan-strict-rules": "^1.1", - "phpunit/phpunit": "^8.5 || ^9.5", - "symfony/cache": "^4.4 || ^5.4 || ^6.0", - "vimeo/psalm": "4.30.0 || 5.24.0" + "phpunit/phpunit": "^8.5.38 || ^9.5", + "symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0" }, "type": "library", "autoload": { @@ -1818,7 +1815,7 @@ ], "support": { "issues": "https://github.com/doctrine/persistence/issues", - "source": "https://github.com/doctrine/persistence/tree/3.3.3" + "source": "https://github.com/doctrine/persistence/tree/3.4.0" }, "funding": [ { @@ -1834,7 +1831,7 @@ "type": "tidelift" } ], - "time": "2024-06-20T10:14:30+00:00" + "time": "2024-10-30T19:48:12+00:00" }, { "name": "drupal/address", @@ -1903,17 +1900,17 @@ }, { "name": "drupal/admin_toolbar", - "version": "3.5.0", + "version": "3.5.1", "source": { "type": "git", "url": "https://git.drupalcode.org/project/admin_toolbar.git", - "reference": "3.5.0" + "reference": "3.5.1" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/admin_toolbar-3.5.0.zip", - "reference": "3.5.0", - "shasum": "099e8d4dc98e1d551b4f9cffdc39599eb8ad04e8" + "url": "https://ftp.drupal.org/files/projects/admin_toolbar-3.5.1.zip", + "reference": "3.5.1", + "shasum": "b5215109836f7fade374fef531231e36c1c9b945" }, "require": { "drupal/core": "^9.5 || ^10 || ^11" @@ -1924,8 +1921,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "3.5.0", - "datestamp": "1722639094", + "version": "3.5.1", + "datestamp": "1730409973", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -2052,17 +2049,17 @@ }, { "name": "drupal/autologout", - "version": "2.0.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://git.drupalcode.org/project/autologout.git", - "reference": "2.0.0" + "reference": "2.0.1" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/autologout-2.0.0.zip", - "reference": "2.0.0", - "shasum": "e9a1d4846cc323eef2eb54a0276023b1f0ff8bd2" + "url": "https://ftp.drupal.org/files/projects/autologout-2.0.1.zip", + "reference": "2.0.1", + "shasum": "61407ffa8b857b1e5d22d03ededac94b5119bd60" }, "require": { "drupal/core": "^9.2 || ^10 || ^11", @@ -2071,8 +2068,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "2.0.0", - "datestamp": "1716413762", + "version": "2.0.1", + "datestamp": "1732235105", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -2395,17 +2392,17 @@ }, { "name": "drupal/ckeditor_templates_ui", - "version": "1.5.0", + "version": "1.6.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/ckeditor_templates_ui.git", - "reference": "8.x-1.5" + "reference": "8.x-1.6" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/ckeditor_templates_ui-8.x-1.5.zip", - "reference": "8.x-1.5", - "shasum": "c8df4dbfdd28f02f5c6a423a74aed0f43663d624" + "url": "https://ftp.drupal.org/files/projects/ckeditor_templates_ui-8.x-1.6.zip", + "reference": "8.x-1.6", + "shasum": "58b0f9b37f79397ee697acc40d29df655ebdb789" }, "require": { "drupal/ckeditor_templates": "*", @@ -2414,8 +2411,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-1.5", - "datestamp": "1679845059", + "version": "8.x-1.6", + "datestamp": "1732954816", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -2428,7 +2425,7 @@ ], "authors": [ { - "name": "Anas_maw", + "name": "anas_maw", "homepage": "https://www.drupal.org/user/3258840" } ], @@ -2665,20 +2662,20 @@ }, { "name": "drupal/content_moderation_notifications", - "version": "3.6.0", + "version": "3.7.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/content_moderation_notifications.git", - "reference": "8.x-3.6" + "reference": "8.x-3.7" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/content_moderation_notifications-8.x-3.6.zip", - "reference": "8.x-3.6", - "shasum": "f475721b95de8d0520053d3101c35c48ea22f61c" + "url": "https://ftp.drupal.org/files/projects/content_moderation_notifications-8.x-3.7.zip", + "reference": "8.x-3.7", + "shasum": "dbe89dc0f9e798ce6c6f14d67874026d49bdad8d" }, "require": { - "drupal/core": "^9 || ^10" + "drupal/core": "^9 || ^10 || ^11" }, "require-dev": { "drupal/token": "^1.0" @@ -2686,8 +2683,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-3.6", - "datestamp": "1695836640", + "version": "8.x-3.7", + "datestamp": "1733438544", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -2704,7 +2701,7 @@ "homepage": "https://www.drupal.org/user/208732" }, { - "name": "Rob Holmes", + "name": "rob holmes", "homepage": "https://www.drupal.org/user/1774034" } ], @@ -2717,16 +2714,16 @@ }, { "name": "drupal/core", - "version": "10.3.6", + "version": "10.3.10", "source": { "type": "git", "url": "https://github.com/drupal/core.git", - "reference": "168ec99f2012aeb4e93c6c7dd4a90dc919ae96c6" + "reference": "3ebb71e9c4ef0c13f683353547551fca49f9a144" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core/zipball/168ec99f2012aeb4e93c6c7dd4a90dc919ae96c6", - "reference": "168ec99f2012aeb4e93c6c7dd4a90dc919ae96c6", + "url": "https://api.github.com/repos/drupal/core/zipball/3ebb71e9c4ef0c13f683353547551fca49f9a144", + "reference": "3ebb71e9c4ef0c13f683353547551fca49f9a144", "shasum": "" }, "require": { @@ -2772,7 +2769,7 @@ "symfony/serializer": "^6.4", "symfony/validator": "^6.4", "symfony/yaml": "^6.4", - "twig/twig": "^3.14.0" + "twig/twig": "^3.14.2" }, "conflict": { "drush/drush": "<12.4.3" @@ -2810,29 +2807,29 @@ "extra": { "drupal-scaffold": { "file-mapping": { - "[project-root]/.editorconfig": "assets/scaffold/files/editorconfig", - "[project-root]/.gitattributes": "assets/scaffold/files/gitattributes", - "[web-root]/.csslintrc": "assets/scaffold/files/csslintrc", - "[web-root]/.eslintignore": "assets/scaffold/files/eslintignore", - "[web-root]/.eslintrc.json": "assets/scaffold/files/eslintrc.json", - "[web-root]/.ht.router.php": "assets/scaffold/files/ht.router.php", "[web-root]/.htaccess": "assets/scaffold/files/htaccess", - "[web-root]/example.gitignore": "assets/scaffold/files/example.gitignore", - "[web-root]/index.php": "assets/scaffold/files/index.php", - "[web-root]/INSTALL.txt": "assets/scaffold/files/drupal.INSTALL.txt", "[web-root]/README.md": "assets/scaffold/files/drupal.README.md", + "[web-root]/index.php": "assets/scaffold/files/index.php", + "[web-root]/.csslintrc": "assets/scaffold/files/csslintrc", "[web-root]/robots.txt": "assets/scaffold/files/robots.txt", "[web-root]/update.php": "assets/scaffold/files/update.php", "[web-root]/web.config": "assets/scaffold/files/web.config", + "[web-root]/INSTALL.txt": "assets/scaffold/files/drupal.INSTALL.txt", + "[web-root]/.eslintignore": "assets/scaffold/files/eslintignore", + "[web-root]/.eslintrc.json": "assets/scaffold/files/eslintrc.json", + "[web-root]/.ht.router.php": "assets/scaffold/files/ht.router.php", "[web-root]/sites/README.txt": "assets/scaffold/files/sites.README.txt", + "[project-root]/.editorconfig": "assets/scaffold/files/editorconfig", + "[web-root]/example.gitignore": "assets/scaffold/files/example.gitignore", + "[web-root]/themes/README.txt": "assets/scaffold/files/themes.README.txt", + "[project-root]/.gitattributes": "assets/scaffold/files/gitattributes", + "[web-root]/modules/README.txt": "assets/scaffold/files/modules.README.txt", + "[web-root]/profiles/README.txt": "assets/scaffold/files/profiles.README.txt", + "[web-root]/sites/example.sites.php": "assets/scaffold/files/example.sites.php", "[web-root]/sites/development.services.yml": "assets/scaffold/files/development.services.yml", "[web-root]/sites/example.settings.local.php": "assets/scaffold/files/example.settings.local.php", - "[web-root]/sites/example.sites.php": "assets/scaffold/files/example.sites.php", "[web-root]/sites/default/default.services.yml": "assets/scaffold/files/default.services.yml", - "[web-root]/sites/default/default.settings.php": "assets/scaffold/files/default.settings.php", - "[web-root]/modules/README.txt": "assets/scaffold/files/modules.README.txt", - "[web-root]/profiles/README.txt": "assets/scaffold/files/profiles.README.txt", - "[web-root]/themes/README.txt": "assets/scaffold/files/themes.README.txt" + "[web-root]/sites/default/default.settings.php": "assets/scaffold/files/default.settings.php" } } }, @@ -2875,13 +2872,13 @@ ], "description": "Drupal is an open source content management platform powering millions of websites and applications.", "support": { - "source": "https://github.com/drupal/core/tree/10.3.6" + "source": "https://github.com/drupal/core/tree/10.3.10" }, - "time": "2024-10-03T08:58:13+00:00" + "time": "2024-11-22T12:51:33+00:00" }, { "name": "drupal/core-composer-scaffold", - "version": "10.3.6", + "version": "10.3.10", "source": { "type": "git", "url": "https://github.com/drupal/core-composer-scaffold.git", @@ -2925,13 +2922,13 @@ "drupal" ], "support": { - "source": "https://github.com/drupal/core-composer-scaffold/tree/10.3.6" + "source": "https://github.com/drupal/core-composer-scaffold/tree/10.3.10" }, "time": "2024-08-22T14:31:34+00:00" }, { "name": "drupal/core-project-message", - "version": "10.3.6", + "version": "10.3.10", "source": { "type": "git", "url": "https://github.com/drupal/core-project-message.git", @@ -2966,22 +2963,22 @@ "drupal" ], "support": { - "source": "https://github.com/drupal/core-project-message/tree/11.0.5" + "source": "https://github.com/drupal/core-project-message/tree/11.1.0-beta1" }, "time": "2023-07-24T07:55:25+00:00" }, { "name": "drupal/core-recommended", - "version": "10.3.6", + "version": "10.3.10", "source": { "type": "git", "url": "https://github.com/drupal/core-recommended.git", - "reference": "5ddec63138dc10869dea5d1cd4e72c977bb9b538" + "reference": "1d739e569c9324bcac1ecc7be600d414386a399b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/drupal/core-recommended/zipball/5ddec63138dc10869dea5d1cd4e72c977bb9b538", - "reference": "5ddec63138dc10869dea5d1cd4e72c977bb9b538", + "url": "https://api.github.com/repos/drupal/core-recommended/zipball/1d739e569c9324bcac1ecc7be600d414386a399b", + "reference": "1d739e569c9324bcac1ecc7be600d414386a399b", "shasum": "" }, "require": { @@ -2990,7 +2987,7 @@ "doctrine/annotations": "~1.14.3", "doctrine/deprecations": "~1.1.3", "doctrine/lexer": "~2.1.1", - "drupal/core": "10.3.6", + "drupal/core": "10.3.10", "egulias/email-validator": "~4.0.2", "guzzlehttp/guzzle": "~7.8.1", "guzzlehttp/promises": "~2.0.2", @@ -3039,7 +3036,7 @@ "symfony/var-dumper": "~v6.4.7", "symfony/var-exporter": "~v6.4.7", "symfony/yaml": "~v6.4.7", - "twig/twig": "~v3.14.0" + "twig/twig": "~v3.14.2" }, "conflict": { "webflo/drupal-core-strict": "*" @@ -3051,9 +3048,9 @@ ], "description": "Core and its dependencies with known-compatible minor versions. Require this project INSTEAD OF drupal/core.", "support": { - "source": "https://github.com/drupal/core-recommended/tree/10.3.6" + "source": "https://github.com/drupal/core-recommended/tree/10.3.10" }, - "time": "2024-10-03T08:58:13+00:00" + "time": "2024-11-22T12:51:33+00:00" }, { "name": "drupal/csv_serialization", @@ -3564,7 +3561,7 @@ ], "authors": [ { - "name": "Berdir", + "name": "berdir", "homepage": "https://www.drupal.org/user/214652" }, { @@ -3701,17 +3698,17 @@ }, { "name": "drupal/feeds", - "version": "3.0.0-rc2", + "version": "3.0.0-rc3", "source": { "type": "git", "url": "https://git.drupalcode.org/project/feeds.git", - "reference": "8.x-3.0-rc2" + "reference": "8.x-3.0-rc3" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/feeds-8.x-3.0-rc2.zip", - "reference": "8.x-3.0-rc2", - "shasum": "ad6c93ccc121b9f921902c5cad3f7b0ac67d0627" + "url": "https://ftp.drupal.org/files/projects/feeds-8.x-3.0-rc3.zip", + "reference": "8.x-3.0-rc3", + "shasum": "21d1f481da86e812288e8dc5b6e240263e9b8a82" }, "require": { "drupal/core": "^10.1 || ^11", @@ -3724,8 +3721,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-3.0-rc2", - "datestamp": "1726755546", + "version": "8.x-3.0-rc3", + "datestamp": "1733412633", "security-coverage": { "status": "not-covered", "message": "RC releases are not covered by Drupal security advisories." @@ -4803,7 +4800,7 @@ ], "authors": [ { - "name": "Berdir", + "name": "berdir", "homepage": "https://www.drupal.org/user/214652" }, { @@ -4823,7 +4820,7 @@ "homepage": "https://www.drupal.org/user/227761" }, { - "name": "Primsi", + "name": "primsi", "homepage": "https://www.drupal.org/user/282629" } ], @@ -5163,7 +5160,7 @@ "homepage": "https://www.drupal.org/u/jansete" }, { - "name": "Manuel Garcia", + "name": "manuel garcia", "homepage": "https://www.drupal.org/user/213194" }, { @@ -5254,36 +5251,37 @@ }, { "name": "drupal/simple_sitemap", - "version": "4.2.1", + "version": "4.2.2", "source": { "type": "git", "url": "https://git.drupalcode.org/project/simple_sitemap.git", - "reference": "4.2.1" + "reference": "4.2.2" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/simple_sitemap-4.2.1.zip", - "reference": "4.2.1", - "shasum": "d96b481571ca2fecdb305e87d2557f9338116864" + "url": "https://ftp.drupal.org/files/projects/simple_sitemap-4.2.2.zip", + "reference": "4.2.2", + "shasum": "1f9c9197d37450fb347a4fa3f10191f5f4b5ef13" }, "require": { "drupal/core": "^10.2 || ^11", "ext-xmlwriter": "*" }, + "conflict": { + "drush/drush": "<12.5.1" + }, + "require-dev": { + "drupal/paragraphs": "^1.18" + }, "type": "drupal-module", "extra": { "drupal": { - "version": "4.2.1", - "datestamp": "1723802052", + "version": "4.2.2", + "datestamp": "1732485885", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" } - }, - "drush": { - "services": { - "drush.services.yml": ">=9" - } } }, "notification-url": "https://packages.drupal.org/8/downloads", @@ -5499,20 +5497,20 @@ }, { "name": "drupal/tome", - "version": "1.12.0", + "version": "1.13.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/tome.git", - "reference": "8.x-1.12" + "reference": "8.x-1.13" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/tome-8.x-1.12.zip", - "reference": "8.x-1.12", - "shasum": "7be3325d6d241b49c8fdd0f673f7ad580fd19b7c" + "url": "https://ftp.drupal.org/files/projects/tome-8.x-1.13.zip", + "reference": "8.x-1.13", + "shasum": "e652ba7bf126287dd4fc7d4fec80bb84df9d39a5" }, "require": { - "drupal/core": "^9 || ^10", + "drupal/core": "^9 || ^10 || ^11", "drupal/tome_static": "*", "drupal/tome_sync": "*" }, @@ -5520,10 +5518,11 @@ "drush/drush": "<11.6" }, "require-dev": { - "drupal/ctools": "*", - "drupal/pathauto": "*", - "drupal/redirect": "*", - "drupal/token": "*", + "drupal/book": "^1.0", + "drupal/ctools": "^4.1", + "drupal/pathauto": "^1.13", + "drupal/redirect": "^1.10", + "drupal/token": "^1.15", "drupal/tome_base": "*", "drupal/tome_static": "*", "drupal/tome_sync": "*" @@ -5531,8 +5530,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-1.12", - "datestamp": "1701628903", + "version": "8.x-1.13", + "datestamp": "1732382851", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -5564,16 +5563,16 @@ }, { "name": "drupal/tome_base", - "version": "1.12.0", + "version": "1.13.0", "require": { - "drupal/core": "^8 || ^9 || ^10", + "drupal/core": "^8 || ^9 || ^10 || ^11", "drupal/tome": "^1" }, "type": "metapackage", "extra": { "drupal": { - "version": "8.x-1.12", - "datestamp": "1701628903", + "version": "8.x-1.13", + "datestamp": "1732382851", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -5602,17 +5601,17 @@ }, { "name": "drupal/tome_static", - "version": "1.12.0", + "version": "1.13.0", "require": { - "drupal/core": "^8 || ^9 || ^10", + "drupal/core": "^8 || ^9 || ^10 || ^11", "drupal/tome": "^1", "drupal/tome_base": "*" }, "type": "metapackage", "extra": { "drupal": { - "version": "8.x-1.12", - "datestamp": "1701628903", + "version": "8.x-1.13", + "datestamp": "1732382851", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -5641,17 +5640,17 @@ }, { "name": "drupal/tome_sync", - "version": "1.12.0", + "version": "1.13.0", "require": { - "drupal/core": "^8 || ^9 || ^10", + "drupal/core": "^8 || ^9 || ^10 || ^11", "drupal/tome": "^1", "drupal/tome_base": "*" }, "type": "metapackage", "extra": { "drupal": { - "version": "8.x-1.12", - "datestamp": "1701628903", + "version": "8.x-1.13", + "datestamp": "1732382851", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -5723,7 +5722,7 @@ ], "authors": [ { - "name": "Chi", + "name": "chi", "homepage": "https://www.drupal.org/user/556138" } ], @@ -5892,22 +5891,25 @@ }, { "name": "drupal/views_data_export", - "version": "1.4.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://git.drupalcode.org/project/views_data_export.git", - "reference": "8.x-1.4" + "reference": "8.x-1.5" }, "dist": { "type": "zip", - "url": "https://ftp.drupal.org/files/projects/views_data_export-8.x-1.4.zip", - "reference": "8.x-1.4", - "shasum": "70dede9fdf50601232f068e67309d361341e88c5" + "url": "https://ftp.drupal.org/files/projects/views_data_export-8.x-1.5.zip", + "reference": "8.x-1.5", + "shasum": "2664bd52dd47b068dec60eecd3c6fc73f2d6c1b8" }, "require": { - "drupal/core": "^9 || ^10", + "drupal/core": "^9 || ^10 || ^11", "drupal/csv_serialization": "~1.4 || ~2.0 || ~3 || ~4" }, + "conflict": { + "phpoffice/phpspreadsheet": "<1.23.0" + }, "require-dev": { "drupal/search_api": "~1.12", "drupal/xls_serialization": "~1.0" @@ -5915,8 +5917,8 @@ "type": "drupal-module", "extra": { "drupal": { - "version": "8.x-1.4", - "datestamp": "1698948991", + "version": "8.x-1.5", + "datestamp": "1732280381", "security-coverage": { "status": "covered", "message": "Covered by Drupal's security advisory policy" @@ -5925,7 +5927,7 @@ }, "notification-url": "https://packages.drupal.org/8/downloads", "license": [ - "GPL-2.0+" + "GPL-2.0-or-later" ], "authors": [ { @@ -6153,23 +6155,23 @@ "sut/libraries/{$name}": [ "type:drupal-library" ], + "sut/themes/unish/{$name}": [ + "drupal/empty_theme" + ], + "sut/drush/contrib/{$name}": [ + "type:drupal-drush" + ], "sut/modules/unish/{$name}": [ "drupal/devel" ], - "sut/themes/unish/{$name}": [ - "drupal/empty_theme" + "sut/themes/contrib/{$name}": [ + "type:drupal-theme" ], "sut/modules/contrib/{$name}": [ "type:drupal-module" ], "sut/profiles/contrib/{$name}": [ "type:drupal-profile" - ], - "sut/themes/contrib/{$name}": [ - "type:drupal-theme" - ], - "sut/drush/contrib/{$name}": [ - "type:drupal-drush" ] } }, @@ -6302,20 +6304,20 @@ }, { "name": "ezyang/htmlpurifier", - "version": "v4.17.0", + "version": "v4.18.0", "source": { "type": "git", "url": "https://github.com/ezyang/htmlpurifier.git", - "reference": "bbc513d79acf6691fa9cf10f192c90dd2957f18c" + "reference": "cb56001e54359df7ae76dc522d08845dc741621b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/bbc513d79acf6691fa9cf10f192c90dd2957f18c", - "reference": "bbc513d79acf6691fa9cf10f192c90dd2957f18c", + "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/cb56001e54359df7ae76dc522d08845dc741621b", + "reference": "cb56001e54359df7ae76dc522d08845dc741621b", "shasum": "" }, "require": { - "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0" + "php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" }, "require-dev": { "cerdic/css-tidy": "^1.7 || ^2.0", @@ -6357,22 +6359,22 @@ ], "support": { "issues": "https://github.com/ezyang/htmlpurifier/issues", - "source": "https://github.com/ezyang/htmlpurifier/tree/v4.17.0" + "source": "https://github.com/ezyang/htmlpurifier/tree/v4.18.0" }, - "time": "2023-11-17T15:01:25+00:00" + "time": "2024-11-01T03:51:45+00:00" }, { "name": "grasmash/expander", - "version": "3.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/grasmash/expander.git", - "reference": "bb1c1a2430957945cf08c5a62f5d72a6aa6a2c82" + "reference": "eea11b9afb0c32483b18b9009f4ca07b770e39f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/grasmash/expander/zipball/bb1c1a2430957945cf08c5a62f5d72a6aa6a2c82", - "reference": "bb1c1a2430957945cf08c5a62f5d72a6aa6a2c82", + "url": "https://api.github.com/repos/grasmash/expander/zipball/eea11b9afb0c32483b18b9009f4ca07b770e39f4", + "reference": "eea11b9afb0c32483b18b9009f4ca07b770e39f4", "shasum": "" }, "require": { @@ -6409,9 +6411,9 @@ "description": "Expands internal property references in PHP arrays file.", "support": { "issues": "https://github.com/grasmash/expander/issues", - "source": "https://github.com/grasmash/expander/tree/3.0.0" + "source": "https://github.com/grasmash/expander/tree/3.0.1" }, - "time": "2022-05-10T13:14:49+00:00" + "time": "2024-11-25T23:28:05+00:00" }, { "name": "grasmash/yaml-cli", @@ -6997,16 +6999,16 @@ }, { "name": "league/container", - "version": "4.2.3", + "version": "4.2.4", "source": { "type": "git", "url": "https://github.com/thephpleague/container.git", - "reference": "72f9bebe7bd623007782a40f5ec305661ab706d8" + "reference": "7ea728b013b9a156c409c6f0fc3624071b742dec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/container/zipball/72f9bebe7bd623007782a40f5ec305661ab706d8", - "reference": "72f9bebe7bd623007782a40f5ec305661ab706d8", + "url": "https://api.github.com/repos/thephpleague/container/zipball/7ea728b013b9a156c409c6f0fc3624071b742dec", + "reference": "7ea728b013b9a156c409c6f0fc3624071b742dec", "shasum": "" }, "require": { @@ -7031,11 +7033,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.x-dev", - "dev-4.x": "4.x-dev", - "dev-3.x": "3.x-dev", + "dev-1.x": "1.x-dev", "dev-2.x": "2.x-dev", - "dev-1.x": "1.x-dev" + "dev-3.x": "3.x-dev", + "dev-4.x": "4.x-dev", + "dev-master": "4.x-dev" } }, "autoload": { @@ -7067,7 +7069,7 @@ ], "support": { "issues": "https://github.com/thephpleague/container/issues", - "source": "https://github.com/thephpleague/container/tree/4.2.3" + "source": "https://github.com/thephpleague/container/tree/4.2.4" }, "funding": [ { @@ -7075,20 +7077,20 @@ "type": "github" } ], - "time": "2024-10-23T12:06:58+00:00" + "time": "2024-11-10T12:42:13+00:00" }, { "name": "league/csv", - "version": "9.18.0", + "version": "9.19.0", "source": { "type": "git", "url": "https://github.com/thephpleague/csv.git", - "reference": "b02d010e4055ae992247f6ffd1e7b103ef2a0790" + "reference": "f81df48a012a9e86d077e74eaff666fd15bfab88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/csv/zipball/b02d010e4055ae992247f6ffd1e7b103ef2a0790", - "reference": "b02d010e4055ae992247f6ffd1e7b103ef2a0790", + "url": "https://api.github.com/repos/thephpleague/csv/zipball/f81df48a012a9e86d077e74eaff666fd15bfab88", + "reference": "f81df48a012a9e86d077e74eaff666fd15bfab88", "shasum": "" }, "require": { @@ -7100,12 +7102,12 @@ "ext-xdebug": "*", "friendsofphp/php-cs-fixer": "^3.64.0", "phpbench/phpbench": "^1.3.1", - "phpstan/phpstan": "^1.12.6", + "phpstan/phpstan": "^1.12.11", "phpstan/phpstan-deprecation-rules": "^1.2.1", - "phpstan/phpstan-phpunit": "^1.4.0", + "phpstan/phpstan-phpunit": "^1.4.1", "phpstan/phpstan-strict-rules": "^1.6.1", - "phpunit/phpunit": "^10.5.16 || ^11.4.1", - "symfony/var-dumper": "^6.4.8 || ^7.1.5" + "phpunit/phpunit": "^10.5.16 || ^11.4.3", + "symfony/var-dumper": "^6.4.8 || ^7.1.8" }, "suggest": { "ext-dom": "Required to use the XMLConverter and the HTMLConverter classes", @@ -7162,7 +7164,7 @@ "type": "github" } ], - "time": "2024-10-18T08:14:48+00:00" + "time": "2024-12-08T08:09:35+00:00" }, { "name": "masterminds/html5", @@ -7282,16 +7284,16 @@ }, { "name": "mglaman/composer-drupal-lenient", - "version": "1.0.5", + "version": "1.0.7", "source": { "type": "git", "url": "https://github.com/mglaman/composer-drupal-lenient.git", - "reference": "37ee92d480eb3bb870a4c7003854978f184e5aa9" + "reference": "bcb9be7f2d3160be43cd1d13a44580734a5afee0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mglaman/composer-drupal-lenient/zipball/37ee92d480eb3bb870a4c7003854978f184e5aa9", - "reference": "37ee92d480eb3bb870a4c7003854978f184e5aa9", + "url": "https://api.github.com/repos/mglaman/composer-drupal-lenient/zipball/bcb9be7f2d3160be43cd1d13a44580734a5afee0", + "reference": "bcb9be7f2d3160be43cd1d13a44580734a5afee0", "shasum": "" }, "require": { @@ -7328,7 +7330,7 @@ ], "support": { "issues": "https://github.com/mglaman/composer-drupal-lenient/issues", - "source": "https://github.com/mglaman/composer-drupal-lenient/tree/1.0.5" + "source": "https://github.com/mglaman/composer-drupal-lenient/tree/1.0.7" }, "funding": [ { @@ -7336,7 +7338,7 @@ "type": "github" } ], - "time": "2024-10-18T15:36:34+00:00" + "time": "2024-11-21T15:59:26+00:00" }, { "name": "mkalkbrenner/php-htmldiff-advanced", @@ -7834,16 +7836,16 @@ }, { "name": "pear/pear-core-minimal", - "version": "v1.10.15", + "version": "v1.10.16", "source": { "type": "git", "url": "https://github.com/pear/pear-core-minimal.git", - "reference": "ce0adade8b97561656ace07cdaac4751c271ea8c" + "reference": "c0f51b45f50683bf5bbf558036854ebc9b54d033" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/ce0adade8b97561656ace07cdaac4751c271ea8c", - "reference": "ce0adade8b97561656ace07cdaac4751c271ea8c", + "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/c0f51b45f50683bf5bbf558036854ebc9b54d033", + "reference": "c0f51b45f50683bf5bbf558036854ebc9b54d033", "shasum": "" }, "require": { @@ -7879,7 +7881,7 @@ "issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=PEAR", "source": "https://github.com/pear/pear-core-minimal" }, - "time": "2024-03-16T18:41:45+00:00" + "time": "2024-11-24T22:27:58+00:00" }, { "name": "pear/pear_exception", @@ -8460,16 +8462,16 @@ }, { "name": "psy/psysh", - "version": "v0.12.4", + "version": "v0.12.7", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "2fd717afa05341b4f8152547f142cd2f130f6818" + "reference": "d73fa3c74918ef4522bb8a3bf9cab39161c4b57c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/2fd717afa05341b4f8152547f142cd2f130f6818", - "reference": "2fd717afa05341b4f8152547f142cd2f130f6818", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/d73fa3c74918ef4522bb8a3bf9cab39161c4b57c", + "reference": "d73fa3c74918ef4522bb8a3bf9cab39161c4b57c", "shasum": "" }, "require": { @@ -8496,12 +8498,12 @@ ], "type": "library", "extra": { - "branch-alias": { - "dev-main": "0.12.x-dev" - }, "bamarni-bin": { "bin-links": false, "forward-command": false + }, + "branch-alias": { + "dev-main": "0.12.x-dev" } }, "autoload": { @@ -8533,9 +8535,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.12.4" + "source": "https://github.com/bobthecow/psysh/tree/v0.12.7" }, - "time": "2024-06-10T01:18:23+00:00" + "time": "2024-12-10T01:58:33+00:00" }, { "name": "ralouphie/getallheaders", @@ -8583,16 +8585,16 @@ }, { "name": "robrichards/xmlseclibs", - "version": "3.1.1", + "version": "3.1.3", "source": { "type": "git", "url": "https://github.com/robrichards/xmlseclibs.git", - "reference": "f8f19e58f26cdb42c54b214ff8a820760292f8df" + "reference": "2bdfd742624d739dfadbd415f00181b4a77aaf07" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/robrichards/xmlseclibs/zipball/f8f19e58f26cdb42c54b214ff8a820760292f8df", - "reference": "f8f19e58f26cdb42c54b214ff8a820760292f8df", + "url": "https://api.github.com/repos/robrichards/xmlseclibs/zipball/2bdfd742624d739dfadbd415f00181b4a77aaf07", + "reference": "2bdfd742624d739dfadbd415f00181b4a77aaf07", "shasum": "" }, "require": { @@ -8619,9 +8621,9 @@ ], "support": { "issues": "https://github.com/robrichards/xmlseclibs/issues", - "source": "https://github.com/robrichards/xmlseclibs/tree/3.1.1" + "source": "https://github.com/robrichards/xmlseclibs/tree/3.1.3" }, - "time": "2020-09-05T13:00:25+00:00" + "time": "2024-11-20T21:13:56+00:00" }, { "name": "sebastian/diff", @@ -8691,16 +8693,16 @@ }, { "name": "symfony/console", - "version": "v6.4.13", + "version": "v6.4.15", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "f793dd5a7d9ae9923e35d0503d08ba734cec1d79" + "reference": "f1fc6f47283e27336e7cebb9e8946c8de7bff9bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/f793dd5a7d9ae9923e35d0503d08ba734cec1d79", - "reference": "f793dd5a7d9ae9923e35d0503d08ba734cec1d79", + "url": "https://api.github.com/repos/symfony/console/zipball/f1fc6f47283e27336e7cebb9e8946c8de7bff9bd", + "reference": "f1fc6f47283e27336e7cebb9e8946c8de7bff9bd", "shasum": "" }, "require": { @@ -8765,7 +8767,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.13" + "source": "https://github.com/symfony/console/tree/v6.4.15" }, "funding": [ { @@ -8781,7 +8783,7 @@ "type": "tidelift" } ], - "time": "2024-10-09T08:40:40+00:00" + "time": "2024-11-06T14:19:14+00:00" }, { "name": "symfony/css-selector", @@ -8850,16 +8852,16 @@ }, { "name": "symfony/dependency-injection", - "version": "v6.4.13", + "version": "v6.4.16", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "728ae8f4e190133ce99d6d5f0bc1e8c8bd7c7a96" + "reference": "7a379d8871f6a36f01559c14e11141cc02eb8dc8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/728ae8f4e190133ce99d6d5f0bc1e8c8bd7c7a96", - "reference": "728ae8f4e190133ce99d6d5f0bc1e8c8bd7c7a96", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/7a379d8871f6a36f01559c14e11141cc02eb8dc8", + "reference": "7a379d8871f6a36f01559c14e11141cc02eb8dc8", "shasum": "" }, "require": { @@ -8911,7 +8913,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.4.13" + "source": "https://github.com/symfony/dependency-injection/tree/v6.4.16" }, "funding": [ { @@ -8927,20 +8929,20 @@ "type": "tidelift" } ], - "time": "2024-10-25T15:07:50+00:00" + "time": "2024-11-25T14:52:46+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "shasum": "" }, "require": { @@ -8978,7 +8980,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" }, "funding": [ { @@ -8994,20 +8996,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/dom-crawler", - "version": "v6.4.13", + "version": "v6.4.16", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "ae074dffb018c37a57071990d16e6152728dd972" + "reference": "4304e6ad5c894a9c72831ad459f627bfd35d766d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/ae074dffb018c37a57071990d16e6152728dd972", - "reference": "ae074dffb018c37a57071990d16e6152728dd972", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/4304e6ad5c894a9c72831ad459f627bfd35d766d", + "reference": "4304e6ad5c894a9c72831ad459f627bfd35d766d", "shasum": "" }, "require": { @@ -9045,7 +9047,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v6.4.13" + "source": "https://github.com/symfony/dom-crawler/tree/v6.4.16" }, "funding": [ { @@ -9061,20 +9063,20 @@ "type": "tidelift" } ], - "time": "2024-10-25T15:07:50+00:00" + "time": "2024-11-13T15:06:22+00:00" }, { "name": "symfony/error-handler", - "version": "v6.4.13", + "version": "v6.4.14", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "e3c78742f86a5b65fe2ac4c4b6b776d92fd7ca0c" + "reference": "9e024324511eeb00983ee76b9aedc3e6ecd993d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/e3c78742f86a5b65fe2ac4c4b6b776d92fd7ca0c", - "reference": "e3c78742f86a5b65fe2ac4c4b6b776d92fd7ca0c", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/9e024324511eeb00983ee76b9aedc3e6ecd993d9", + "reference": "9e024324511eeb00983ee76b9aedc3e6ecd993d9", "shasum": "" }, "require": { @@ -9120,7 +9122,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.4.13" + "source": "https://github.com/symfony/error-handler/tree/v6.4.14" }, "funding": [ { @@ -9136,7 +9138,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:18:03+00:00" + "time": "2024-11-05T15:34:40+00:00" }, { "name": "symfony/event-dispatcher", @@ -9220,16 +9222,16 @@ }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50" + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50", - "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", "shasum": "" }, "require": { @@ -9276,7 +9278,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" }, "funding": [ { @@ -9292,7 +9294,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/filesystem", @@ -9426,16 +9428,16 @@ }, { "name": "symfony/http-foundation", - "version": "v6.4.13", + "version": "v6.4.16", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "4c0341b3e0a7291e752c69d2a1ed9a84b68d604c" + "reference": "431771b7a6f662f1575b3cfc8fd7617aa9864d57" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/4c0341b3e0a7291e752c69d2a1ed9a84b68d604c", - "reference": "4c0341b3e0a7291e752c69d2a1ed9a84b68d604c", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/431771b7a6f662f1575b3cfc8fd7617aa9864d57", + "reference": "431771b7a6f662f1575b3cfc8fd7617aa9864d57", "shasum": "" }, "require": { @@ -9445,12 +9447,12 @@ "symfony/polyfill-php83": "^1.27" }, "conflict": { - "symfony/cache": "<6.3" + "symfony/cache": "<6.4.12|>=7.0,<7.1.5" }, "require-dev": { "doctrine/dbal": "^2.13.1|^3|^4", "predis/predis": "^1.1|^2.0", - "symfony/cache": "^6.3|^7.0", + "symfony/cache": "^6.4.12|^7.1.5", "symfony/dependency-injection": "^5.4|^6.0|^7.0", "symfony/expression-language": "^5.4|^6.0|^7.0", "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4|^7.0", @@ -9483,7 +9485,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.4.13" + "source": "https://github.com/symfony/http-foundation/tree/v6.4.16" }, "funding": [ { @@ -9499,20 +9501,20 @@ "type": "tidelift" } ], - "time": "2024-10-11T19:20:58+00:00" + "time": "2024-11-13T18:58:10+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.4.13", + "version": "v6.4.16", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "4474015c363ec0cd3bf47d55657e68630dbae66e" + "reference": "8838b5b21d807923b893ccbfc2cbeda0f1bc00f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/4474015c363ec0cd3bf47d55657e68630dbae66e", - "reference": "4474015c363ec0cd3bf47d55657e68630dbae66e", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/8838b5b21d807923b893ccbfc2cbeda0f1bc00f0", + "reference": "8838b5b21d807923b893ccbfc2cbeda0f1bc00f0", "shasum": "" }, "require": { @@ -9597,7 +9599,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.4.13" + "source": "https://github.com/symfony/http-kernel/tree/v6.4.16" }, "funding": [ { @@ -9613,7 +9615,7 @@ "type": "tidelift" } ], - "time": "2024-10-27T13:00:29+00:00" + "time": "2024-11-27T12:49:36+00:00" }, { "name": "symfony/mailer", @@ -9806,8 +9808,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -9962,8 +9964,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -10042,8 +10044,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -10124,8 +10126,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -10208,8 +10210,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -10282,8 +10284,8 @@ "type": "metapackage", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "notification-url": "https://packagist.org/downloads/", @@ -10347,8 +10349,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -10427,8 +10429,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -10504,8 +10506,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -10562,16 +10564,16 @@ }, { "name": "symfony/process", - "version": "v6.4.13", + "version": "v6.4.15", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "1f9f59b46880201629df3bd950fc5ae8c55b960f" + "reference": "3cb242f059c14ae08591c5c4087d1fe443564392" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/1f9f59b46880201629df3bd950fc5ae8c55b960f", - "reference": "1f9f59b46880201629df3bd950fc5ae8c55b960f", + "url": "https://api.github.com/repos/symfony/process/zipball/3cb242f059c14ae08591c5c4087d1fe443564392", + "reference": "3cb242f059c14ae08591c5c4087d1fe443564392", "shasum": "" }, "require": { @@ -10603,7 +10605,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.4.13" + "source": "https://github.com/symfony/process/tree/v6.4.15" }, "funding": [ { @@ -10619,7 +10621,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:18:03+00:00" + "time": "2024-11-06T14:19:14+00:00" }, { "name": "symfony/psr-http-message-bridge", @@ -10706,16 +10708,16 @@ }, { "name": "symfony/routing", - "version": "v6.4.13", + "version": "v6.4.16", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "640a74250d13f9c30d5ca045b6aaaabcc8215278" + "reference": "91e02e606b4b705c2f4fb42f7e7708b7923a3220" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/640a74250d13f9c30d5ca045b6aaaabcc8215278", - "reference": "640a74250d13f9c30d5ca045b6aaaabcc8215278", + "url": "https://api.github.com/repos/symfony/routing/zipball/91e02e606b4b705c2f4fb42f7e7708b7923a3220", + "reference": "91e02e606b4b705c2f4fb42f7e7708b7923a3220", "shasum": "" }, "require": { @@ -10769,7 +10771,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v6.4.13" + "source": "https://github.com/symfony/routing/tree/v6.4.16" }, "funding": [ { @@ -10785,20 +10787,20 @@ "type": "tidelift" } ], - "time": "2024-10-01T08:30:56+00:00" + "time": "2024-11-13T15:31:34+00:00" }, { "name": "symfony/serializer", - "version": "v6.4.13", + "version": "v6.4.15", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "8be421505938b11a0ca4f656e4322232236386f0" + "reference": "9d862d66198f3c2e30404228629ef4c18d5d608e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/8be421505938b11a0ca4f656e4322232236386f0", - "reference": "8be421505938b11a0ca4f656e4322232236386f0", + "url": "https://api.github.com/repos/symfony/serializer/zipball/9d862d66198f3c2e30404228629ef4c18d5d608e", + "reference": "9d862d66198f3c2e30404228629ef4c18d5d608e", "shasum": "" }, "require": { @@ -10867,7 +10869,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v6.4.13" + "source": "https://github.com/symfony/serializer/tree/v6.4.15" }, "funding": [ { @@ -10883,20 +10885,20 @@ "type": "tidelift" } ], - "time": "2024-10-03T09:58:04+00:00" + "time": "2024-10-23T13:25:59+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", - "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", "shasum": "" }, "require": { @@ -10950,7 +10952,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" }, "funding": [ { @@ -10966,20 +10968,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/string", - "version": "v6.4.13", + "version": "v6.4.15", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "38371c60c71c72b3d64d8d76f6b1bb81a2cc3627" + "reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/38371c60c71c72b3d64d8d76f6b1bb81a2cc3627", - "reference": "38371c60c71c72b3d64d8d76f6b1bb81a2cc3627", + "url": "https://api.github.com/repos/symfony/string/zipball/73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f", + "reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f", "shasum": "" }, "require": { @@ -11036,7 +11038,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.4.13" + "source": "https://github.com/symfony/string/tree/v6.4.15" }, "funding": [ { @@ -11052,20 +11054,20 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:18:03+00:00" + "time": "2024-11-13T13:31:12+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a" + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", - "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/4667ff3bd513750603a09c8dedbea942487fb07c", + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c", "shasum": "" }, "require": { @@ -11114,7 +11116,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.5.1" }, "funding": [ { @@ -11130,20 +11132,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/validator", - "version": "v6.4.13", + "version": "v6.4.16", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "68e0bf4522756269d9bff801a16701b2ed5eb730" + "reference": "9b0d1988b56511706bc91d96ead39acd77aaf34d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/68e0bf4522756269d9bff801a16701b2ed5eb730", - "reference": "68e0bf4522756269d9bff801a16701b2ed5eb730", + "url": "https://api.github.com/repos/symfony/validator/zipball/9b0d1988b56511706bc91d96ead39acd77aaf34d", + "reference": "9b0d1988b56511706bc91d96ead39acd77aaf34d", "shasum": "" }, "require": { @@ -11211,7 +11213,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v6.4.13" + "source": "https://github.com/symfony/validator/tree/v6.4.16" }, "funding": [ { @@ -11227,20 +11229,20 @@ "type": "tidelift" } ], - "time": "2024-10-25T15:07:50+00:00" + "time": "2024-11-27T09:48:51+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.4.13", + "version": "v6.4.15", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "2acb151474ed8cb43624e3f41a0bf7c4c8ce4f41" + "reference": "38254d5a5ac2e61f2b52f9caf54e7aa3c9d36b80" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/2acb151474ed8cb43624e3f41a0bf7c4c8ce4f41", - "reference": "2acb151474ed8cb43624e3f41a0bf7c4c8ce4f41", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/38254d5a5ac2e61f2b52f9caf54e7aa3c9d36b80", + "reference": "38254d5a5ac2e61f2b52f9caf54e7aa3c9d36b80", "shasum": "" }, "require": { @@ -11296,7 +11298,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.13" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.15" }, "funding": [ { @@ -11312,7 +11314,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:18:03+00:00" + "time": "2024-11-08T15:28:48+00:00" }, { "name": "symfony/var-exporter", @@ -11465,16 +11467,16 @@ }, { "name": "twig/twig", - "version": "v3.14.0", + "version": "v3.14.2", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "126b2c97818dbff0cdf3fbfc881aedb3d40aae72" + "reference": "0b6f9d8370bb3b7f1ce5313ed8feb0fafd6e399a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/126b2c97818dbff0cdf3fbfc881aedb3d40aae72", - "reference": "126b2c97818dbff0cdf3fbfc881aedb3d40aae72", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/0b6f9d8370bb3b7f1ce5313ed8feb0fafd6e399a", + "reference": "0b6f9d8370bb3b7f1ce5313ed8feb0fafd6e399a", "shasum": "" }, "require": { @@ -11528,7 +11530,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.14.0" + "source": "https://github.com/twigphp/Twig/tree/v3.14.2" }, "funding": [ { @@ -11540,7 +11542,7 @@ "type": "tidelift" } ], - "time": "2024-09-09T17:55:12+00:00" + "time": "2024-11-07T12:36:22+00:00" }, { "name": "webflo/drupal-finder", @@ -11645,7 +11647,448 @@ "time": "2023-04-15T19:07:00+00:00" } ], - "packages-dev": [], + "packages-dev": [ + { + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/PHPCSStandards/composer-installer.git", + "reference": "4be43904336affa5c2f70744a348312336afd0da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/4be43904336affa5c2f70744a348312336afd0da", + "reference": "4be43904336affa5c2f70744a348312336afd0da", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0", + "php": ">=5.4", + "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" + }, + "require-dev": { + "composer/composer": "*", + "ext-json": "*", + "ext-zip": "*", + "php-parallel-lint/php-parallel-lint": "^1.3.1", + "phpcompatibility/php-compatibility": "^9.0", + "yoast/phpunit-polyfills": "^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Franck Nijhof", + "email": "franck.nijhof@dealerdirect.com", + "homepage": "http://www.frenck.nl", + "role": "Developer / IT Manager" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer Standards Composer Installer Plugin", + "homepage": "http://www.dealerdirect.com", + "keywords": [ + "PHPCodeSniffer", + "PHP_CodeSniffer", + "code quality", + "codesniffer", + "composer", + "installer", + "phpcbf", + "phpcs", + "plugin", + "qa", + "quality", + "standard", + "standards", + "style guide", + "stylecheck", + "tests" + ], + "support": { + "issues": "https://github.com/PHPCSStandards/composer-installer/issues", + "source": "https://github.com/PHPCSStandards/composer-installer" + }, + "time": "2023-01-05T11:28:13+00:00" + }, + { + "name": "drupal/coder", + "version": "8.3.26", + "source": { + "type": "git", + "url": "https://github.com/pfrenssen/coder.git", + "reference": "fd98546ce3373aa7767240901eda47963ce64c82" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/pfrenssen/coder/zipball/fd98546ce3373aa7767240901eda47963ce64c82", + "reference": "fd98546ce3373aa7767240901eda47963ce64c82", + "shasum": "" + }, + "require": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.1 || ^1.0.0", + "ext-mbstring": "*", + "php": ">=7.2", + "sirbrillig/phpcs-variable-analysis": "^2.11.7", + "slevomat/coding-standard": "^8.11", + "squizlabs/php_codesniffer": "^3.9.1", + "symfony/yaml": ">=3.4.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.7.12", + "phpunit/phpunit": "^8.0" + }, + "type": "phpcodesniffer-standard", + "autoload": { + "psr-4": { + "Drupal\\": "coder_sniffer/Drupal/", + "DrupalPractice\\": "coder_sniffer/DrupalPractice/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "description": "Coder is a library to review Drupal code.", + "homepage": "https://www.drupal.org/project/coder", + "keywords": [ + "code review", + "phpcs", + "standards" + ], + "support": { + "issues": "https://www.drupal.org/project/issues/coder", + "source": "https://www.drupal.org/project/coder" + }, + "time": "2024-11-28T23:14:29+00:00" + }, + { + "name": "php-parallel-lint/php-parallel-lint", + "version": "v1.4.0", + "source": { + "type": "git", + "url": "https://github.com/php-parallel-lint/PHP-Parallel-Lint.git", + "reference": "6db563514f27e19595a19f45a4bf757b6401194e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-parallel-lint/PHP-Parallel-Lint/zipball/6db563514f27e19595a19f45a4bf757b6401194e", + "reference": "6db563514f27e19595a19f45a4bf757b6401194e", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=5.3.0" + }, + "replace": { + "grogy/php-parallel-lint": "*", + "jakub-onderka/php-parallel-lint": "*" + }, + "require-dev": { + "nette/tester": "^1.3 || ^2.0", + "php-parallel-lint/php-console-highlighter": "0.* || ^1.0", + "squizlabs/php_codesniffer": "^3.6" + }, + "suggest": { + "php-parallel-lint/php-console-highlighter": "Highlight syntax in code snippet" + }, + "bin": [ + "parallel-lint" + ], + "type": "library", + "autoload": { + "classmap": [ + "./src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Jakub Onderka", + "email": "ahoj@jakubonderka.cz" + } + ], + "description": "This tool checks the syntax of PHP files about 20x faster than serial check.", + "homepage": "https://github.com/php-parallel-lint/PHP-Parallel-Lint", + "keywords": [ + "lint", + "static analysis" + ], + "support": { + "issues": "https://github.com/php-parallel-lint/PHP-Parallel-Lint/issues", + "source": "https://github.com/php-parallel-lint/PHP-Parallel-Lint/tree/v1.4.0" + }, + "time": "2024-03-27T12:14:49+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "1.33.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/82a311fd3690fb2bf7b64d5c98f912b3dd746140", + "reference": "82a311fd3690fb2bf7b64d5c98f912b3dd746140", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^4.15", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.5", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.33.0" + }, + "time": "2024-10-13T11:25:22+00:00" + }, + { + "name": "sirbrillig/phpcs-variable-analysis", + "version": "v2.11.21", + "source": { + "type": "git", + "url": "https://github.com/sirbrillig/phpcs-variable-analysis.git", + "reference": "eb2b351927098c24860daa7484e290d3eed693be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sirbrillig/phpcs-variable-analysis/zipball/eb2b351927098c24860daa7484e290d3eed693be", + "reference": "eb2b351927098c24860daa7484e290d3eed693be", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "squizlabs/php_codesniffer": "^3.5.6" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || ^1.0", + "phpcsstandards/phpcsdevcs": "^1.1", + "phpstan/phpstan": "^1.7", + "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.5 || ^7.0 || ^8.0 || ^9.0 || ^10.5.32 || ^11.3.3", + "sirbrillig/phpcs-import-detection": "^1.1", + "vimeo/psalm": "^0.2 || ^0.3 || ^1.1 || ^4.24 || ^5.0" + }, + "type": "phpcodesniffer-standard", + "autoload": { + "psr-4": { + "VariableAnalysis\\": "VariableAnalysis/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "authors": [ + { + "name": "Sam Graham", + "email": "php-codesniffer-variableanalysis@illusori.co.uk" + }, + { + "name": "Payton Swick", + "email": "payton@foolord.com" + } + ], + "description": "A PHPCS sniff to detect problems with variables.", + "keywords": [ + "phpcs", + "static analysis" + ], + "support": { + "issues": "https://github.com/sirbrillig/phpcs-variable-analysis/issues", + "source": "https://github.com/sirbrillig/phpcs-variable-analysis", + "wiki": "https://github.com/sirbrillig/phpcs-variable-analysis/wiki" + }, + "time": "2024-12-02T16:37:49+00:00" + }, + { + "name": "slevomat/coding-standard", + "version": "8.15.0", + "source": { + "type": "git", + "url": "https://github.com/slevomat/coding-standard.git", + "reference": "7d1d957421618a3803b593ec31ace470177d7817" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/7d1d957421618a3803b593ec31ace470177d7817", + "reference": "7d1d957421618a3803b593ec31ace470177d7817", + "shasum": "" + }, + "require": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0", + "php": "^7.2 || ^8.0", + "phpstan/phpdoc-parser": "^1.23.1", + "squizlabs/php_codesniffer": "^3.9.0" + }, + "require-dev": { + "phing/phing": "2.17.4", + "php-parallel-lint/php-parallel-lint": "1.3.2", + "phpstan/phpstan": "1.10.60", + "phpstan/phpstan-deprecation-rules": "1.1.4", + "phpstan/phpstan-phpunit": "1.3.16", + "phpstan/phpstan-strict-rules": "1.5.2", + "phpunit/phpunit": "8.5.21|9.6.8|10.5.11" + }, + "type": "phpcodesniffer-standard", + "extra": { + "branch-alias": { + "dev-master": "8.x-dev" + } + }, + "autoload": { + "psr-4": { + "SlevomatCodingStandard\\": "SlevomatCodingStandard/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", + "keywords": [ + "dev", + "phpcs" + ], + "support": { + "issues": "https://github.com/slevomat/coding-standard/issues", + "source": "https://github.com/slevomat/coding-standard/tree/8.15.0" + }, + "funding": [ + { + "url": "https://github.com/kukulich", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", + "type": "tidelift" + } + ], + "time": "2024-03-09T15:20:58+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.11.1", + "source": { + "type": "git", + "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", + "reference": "19473c30efe4f7b3cd42522d0b2e6e7f243c6f87" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/19473c30efe4f7b3cd42522d0b2e6e7f243c6f87", + "reference": "19473c30efe4f7b3cd42522d0b2e6e7f243c6f87", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" + }, + "bin": [ + "bin/phpcbf", + "bin/phpcs" + ], + "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": "Former lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "Current lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHPCSStandards/PHP_CodeSniffer/issues", + "security": "https://github.com/PHPCSStandards/PHP_CodeSniffer/security/policy", + "source": "https://github.com/PHPCSStandards/PHP_CodeSniffer", + "wiki": "https://github.com/PHPCSStandards/PHP_CodeSniffer/wiki" + }, + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + } + ], + "time": "2024-11-16T12:02:36+00:00" + } + ], "aliases": [], "minimum-stability": "dev", "stability-flags": { @@ -11659,7 +12102,7 @@ }, "prefer-stable": true, "prefer-lowest": false, - "platform": {}, - "platform-dev": {}, - "plugin-api-version": "2.6.0" + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.2.0" } diff --git a/config/sync/menu_breadcrumb.settings.yml b/config/sync/menu_breadcrumb.settings.yml index f9b4752401..71042fa0a8 100644 --- a/config/sync/menu_breadcrumb.settings.yml +++ b/config/sync/menu_breadcrumb.settings.yml @@ -12,13 +12,18 @@ add_home: true front_title: 0 exclude_empty_url: false exclude_disabled_menu_items: false -derived_active_trail: false +derived_active_trail: true menu_breadcrumb_menus: main: enabled: 0 weight: -10 taxattach: 0 langhandle: 0 + account: + enabled: 0 + weight: 0 + taxattach: 0 + langhandle: 0 admin: enabled: 0 weight: 0 @@ -44,12 +49,27 @@ menu_breadcrumb_menus: weight: 0 taxattach: 0 langhandle: 1 + primary-footer: + enabled: 0 + weight: 0 + taxattach: 0 + langhandle: 0 + primary-footer-spanish: + enabled: 0 + weight: 0 + taxattach: 0 + langhandle: 0 tools: enabled: 0 weight: 0 taxattach: 0 langhandle: 0 - account: + top-navigation: + enabled: 0 + weight: 0 + taxattach: 0 + langhandle: 0 + top-navigation-es: enabled: 0 weight: 0 taxattach: 0 diff --git a/docker-compose.yml b/docker-compose.yml index c213edbda2..87554af9a7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -26,7 +26,7 @@ services: volumes: - .:/var/www:delegated - ./.docker/src-cms/etc/periodic/1min/generate-static-site:/etc/periodic/1min/generate-static-site:delegated - #- ./.docker/src-cms/50_xdebug.ini:/etc/php81/conf.d/50_xdebug.ini:delegated + # - ./.docker/src-cms/50_xdebug.ini:/etc/php83/conf.d/50_xdebug.ini:delegated env_file: - ./env.local environment: diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh index 8438bc9d06..7672ed3070 100755 --- a/scripts/bootstrap.sh +++ b/scripts/bootstrap.sh @@ -96,12 +96,12 @@ export S3_PROXY_WEB export S3_PROXY_CMS export S3_PROXY_PATH_CMS -if [ -f "/etc/php81/php-fpm.d/env.conf.tmpl" ]; then - cp /etc/php81/php-fpm.d/env.conf.tmpl /etc/php81/php-fpm.d/env.conf - echo "env[S3_PROXY_PATH_CMS] = "$S3_PROXY_PATH_CMS >> /etc/php81/php-fpm.d/env.conf - echo "env[S3_PROXY_CMS] = "$S3_PROXY_CMS >> /etc/php81/php-fpm.d/env.conf - echo "env[S3_ROOT_CMS] = "$S3_ROOT_CMS >> /etc/php81/php-fpm.d/env.conf - echo "env[S3_HOST] = "$S3_HOST >> /etc/php81/php-fpm.d/env.conf +if [ -f "/etc/php83/php-fpm.d/env.conf.tmpl" ]; then + cp /etc/php83/php-fpm.d/env.conf.tmpl /etc/php83/php-fpm.d/env.conf + echo "env[S3_PROXY_PATH_CMS] = "$S3_PROXY_PATH_CMS >> /etc/php83/php-fpm.d/env.conf + echo "env[S3_PROXY_CMS] = "$S3_PROXY_CMS >> /etc/php83/php-fpm.d/env.conf + echo "env[S3_ROOT_CMS] = "$S3_ROOT_CMS >> /etc/php83/php-fpm.d/env.conf + echo "env[S3_HOST] = "$S3_HOST >> /etc/php83/php-fpm.d/env.conf fi export DNS_SERVER=${DNS_SERVER:-$(grep -i '^nameserver' /etc/resolv.conf|head -n1|cut -d ' ' -f2)} @@ -136,7 +136,7 @@ for FILE in /etc/nginx/*/*.conf.tmpl /etc/nginx/*.conf.tmpl; do done # update new relic with environment specific settings -if [ -f "/etc/php81/conf.d/newrelic.ini" ]; then +if [ -f "/etc/php83/conf.d/newrelic.ini" ]; then if [ -n "$NEW_RELIC_LICENSE_KEY" ] && [ "$NEW_RELIC_LICENSE_KEY" != "null" ]; then echo "Setting up New Relic ... " sed -i \ @@ -145,20 +145,20 @@ if [ -f "/etc/php81/conf.d/newrelic.ini" ]; then -e "s|;\?newrelic.appname =.*|newrelic.appname = \"${NEW_RELIC_APP_NAME:-CMS-dev;USA.gov}\"|" \ -e "s|;\?newrelic.daemon.loglevel =.*|newrelic.daemon.loglevel = \"${NEW_RELIC_LOG_LEVEL:-warning}\"|" \ -e "s|;\?newrelic.enabled =.*|newrelic.enabled = true|" \ - /etc/php81/conf.d/newrelic.ini + /etc/php83/conf.d/newrelic.ini else echo "Turning off New Relic ... " sed -i \ -e "s/;\?newrelic.enabled =.*/newrelic.enabled = false/" \ - /etc/php81/conf.d/newrelic.ini + /etc/php83/conf.d/newrelic.ini fi if [ "NoProxy" = "${PROXYROUTE:NoProxy}" ]; then # TODO: what to do here? PROXYROUTE should be set! sed -i \ -e "s|;\?newrelic.daemon.ssl_ca_bundle =.*|newrelic.daemon.ssl_ca_bundle = \"/etc/ssl/certs/ca-certificates.crt\"|" \ -e "s|;\?newrelic.daemon.ssl_ca_path =.*|newrelic.daemon.ssl_ca_path = \"/etc/ssl/certs/\"|" \ - /etc/php81/conf.d/newrelic.ini + /etc/php83/conf.d/newrelic.ini else # We are probably being needlessly redundant in setting both ssl_ca_bundle and ssl_ca_path. # NR says it will search ssl_ca_bundle first, then the certificates in ssl_ca_path. We have ssl_ca_bundle within ssl_ca_path, so ... @@ -166,7 +166,7 @@ if [ -f "/etc/php81/conf.d/newrelic.ini" ]; then -e "s|;\?newrelic.daemon.ssl_ca_bundle =.*|newrelic.daemon.ssl_ca_bundle = \"/etc/ssl/certs/ca-certificates.crt\"|" \ -e "s|;\?newrelic.daemon.ssl_ca_path =.*|newrelic.daemon.ssl_ca_path = \"/etc/ssl/certs/\"|" \ -e "s|;\?newrelic.daemon.proxy =.*|newrelic.daemon.proxy = \"$PROXYROUTE\"|" \ - /etc/php81/conf.d/newrelic.ini + /etc/php83/conf.d/newrelic.ini fi fi diff --git a/scripts/tome-static.sh b/scripts/tome-static.sh index a0c202c578..4b4f4dd61d 100755 --- a/scripts/tome-static.sh +++ b/scripts/tome-static.sh @@ -32,5 +32,13 @@ mkdir -p /var/www/html # time drush tome:static -y --uri=$URI --process-count=5 --path-count=1 time drush tome:static -y --uri=$URI --process-count=$TOME_PROCESS_COUNT --path-count=10 TOME_SUCCESS=$? + echo "Finished Static Site Generation : "$(date) + +if [ "$TOME_SUCCESS" -eq 0 ]; then + # path is relative to drupal's web dir + time drush usapubcsv --uri=$URI modules/custom/usagov_ssg_postprocessing/files/published-pages.csv + echo "Exported published-pages.csv" +fi + exit $TOME_SUCCESS diff --git a/web/modules/custom/usa_twig_vars/src/TaxonomyDatalayerBuilder.php b/web/modules/custom/usa_twig_vars/src/TaxonomyDatalayerBuilder.php index cce076f5f1..264cb50d86 100644 --- a/web/modules/custom/usa_twig_vars/src/TaxonomyDatalayerBuilder.php +++ b/web/modules/custom/usa_twig_vars/src/TaxonomyDatalayerBuilder.php @@ -4,7 +4,7 @@ use Drupal\Core\Breadcrumb\BreadcrumbManager; use Drupal\Core\Entity\EntityMalformedException; -use Drupal\Core\Routing\CurrentRouteMatch; +use Drupal\Core\Routing\RouteMatchInterface; use Drupal\node\Entity\Node; /** @@ -48,7 +48,7 @@ class TaxonomyDatalayerBuilder { private string $isFront; public function __construct( - private CurrentRouteMatch $routeMatch, + private RouteMatchInterface $routeMatch, private BreadcrumbManager $breadcrumbManager, public Node $node, bool $isFront, @@ -151,7 +151,8 @@ public function fromBreadcrumb(): array { break; } - $url = $crumb->getUrl()->toString() ?: $this->node->toUrl()->toString(); + $url = $crumb->getUrl()->setOption('language', $this->node->language())->toString() + ?: $this->node->toUrl()->setOption('language', $this->node->language())->toString(); if ($url === '/es') { $url = self::HOME_URL_ES; diff --git a/web/modules/custom/usa_twig_vars/usa_twig_vars.module b/web/modules/custom/usa_twig_vars/usa_twig_vars.module index 35c7fbbb78..e6f71cb75b 100644 --- a/web/modules/custom/usa_twig_vars/usa_twig_vars.module +++ b/web/modules/custom/usa_twig_vars/usa_twig_vars.module @@ -7,7 +7,6 @@ use Drupal\Core\Render\Markup; use Drupal\Core\Url; -use Drupal\block\Entity\Block; use Drupal\node\Entity\Node; use Drupal\node\NodeInterface; use Drupal\path_alias\PathAliasInterface; diff --git a/web/modules/custom/usagov_benefit_category_search/src/EventSubscriber/DatalayerAlterSubscriber.php b/web/modules/custom/usagov_benefit_category_search/src/EventSubscriber/DatalayerAlterSubscriber.php index 7c7dddfecc..8c7555faa0 100644 --- a/web/modules/custom/usagov_benefit_category_search/src/EventSubscriber/DatalayerAlterSubscriber.php +++ b/web/modules/custom/usagov_benefit_category_search/src/EventSubscriber/DatalayerAlterSubscriber.php @@ -25,7 +25,14 @@ public static function getSubscribedEvents() { * Adds category information to the datalayer. */ public function onDatalayerAlter(DatalayerAlterEvent $event): void { - $node = \Drupal::routeMatch()->getParameter('node'); + + // This listener is only interested in nodes, which have numeric IDs. + // Taxonomy terms IDs are prefixed with "t_" + if (!isset($event->datalayer['nodeID']) || !is_numeric($event->datalayer['nodeID'])) { + return; + } + + $node = Node::load($event->datalayer['nodeID']); $event->datalayer['hasBenefitCategory'] = FALSE; if ($node instanceof Node && $node->getType() === 'basic_page') { diff --git a/web/modules/custom/usagov_ssg_postprocessing/src/Data/PublishedPagesRow.php b/web/modules/custom/usagov_ssg_postprocessing/src/Data/PublishedPagesRow.php new file mode 100644 index 0000000000..7ff92993bf --- /dev/null +++ b/web/modules/custom/usagov_ssg_postprocessing/src/Data/PublishedPagesRow.php @@ -0,0 +1,232 @@ +getId()) { + 'es' => "USAGov Español", + 'en' => "USAGov English", + default => "USAGov English", + }; + } + + private static function getHierarchy(array $data): int { + $texts = array_filter($data, fn($key) => str_starts_with($key, 'Taxonomy_URL_'), ARRAY_FILTER_USE_KEY); + return count(array_unique($texts)); + } + + public function toArray(): array { + $array = [ + $this->hierarchy, + $this->pageType, + $this->pageSubType ?? '', + $this->contentType, + $this->friendlyURL, + $this->pageID, + $this->pageTitle, + $this->fullURL, + $this->taxonomyText1, + $this->taxonomyText2, + $this->taxonomyText3, + $this->taxonomyText4, + $this->taxonomyText5, + $this->taxonomyText6, + $this->taxonomyURL1, + $this->taxonomyURL2, + $this->taxonomyURL3, + $this->taxonomyURL4, + $this->taxonomyURL5, + $this->taxonomyURL6, + $this->isHomePage, + $this->toggleURL, + $this->hasBenefitCategory, + ]; + + // Keeps existing behavior of only including these columns if they have something + if ($this->hasBenefitCategory !== "") { + $array[] = $this->benefitCategories; + } + return $array; + } + + public static function datalayerForNode(array $data, Node $node, string $baseURL): self { + $title = $node->getTitle(); + + // Federal Agency nodes tack on the acronym because the original implementation + // pulled the title from the HTML + if ($node->getType() === 'directory_record') { + $acronym = $node->get('field_acronym')->getValue(); + if ($acronym) { + $title = sprintf("%s (%s)", trim($title), trim($acronym[0]['value'])); + } + } + + if ($data['homepageTest'] === 'homepage' && $data['language'] === 'en') { + $friendlyURL = TaxonomyDatalayerBuilder::HOME_URL_EN; + $fullURL = $baseURL . TaxonomyDatalayerBuilder::HOME_URL_EN; + } + elseif ($data['homepageTest'] === 'homepage' && $data['language'] === 'es') { + $friendlyURL = TaxonomyDatalayerBuilder::HOME_URL_ES; + $fullURL = $baseURL . TaxonomyDatalayerBuilder::HOME_URL_ES; + } + else { + $friendlyURL = $node->toUrl('canonical', + options: ['language' => $node->language()] + )->toString(); + $fullURL = $node->toUrl( + options: ['absolute' => TRUE, 'language' => $node->language()] + )->toString(); + } + + $toggleURL = NULL; + if (isset($node->field_language_toggle[0]) && $node->field_language_toggle[0]?->target_id) { + if ($data['homepageTest'] === 'homepage' && $data['language'] === 'en') { + $toggleURL = $baseURL . TaxonomyDatalayerBuilder::HOME_URL_ES; + } + elseif ($data['homepageTest'] === 'homepage' && $data['language'] === 'es') { + $toggleURL = $baseURL . TaxonomyDatalayerBuilder::HOME_URL_EN; + } + else { + $toggleNode = \Drupal::entityTypeManager() + ->getStorage('node') + ->load($node->field_language_toggle[0]->target_id); + $url = Url::fromRoute( + 'entity.node.canonical', + ['node' => $toggleNode->id()], + ['absolute' => TRUE, 'language' => $toggleNode->language()] + ); + $toggleURL = $url->toString(); + } + } + + return new self( + hierarchy: self::getHierarchy($data), + pageType: $data['Page_Type'], + pageSubType: $data['basicPagesubType'], + contentType: $data['contentType'], + friendlyURL: $friendlyURL, + pageID: $data['nodeID'], + pageTitle: $title, + fullURL: $fullURL, + taxonomyText1: self::getTaxLevel1($node->language()), + taxonomyText2: $data['Taxonomy_Text_2'], + taxonomyText3: $data['Taxonomy_Text_3'], + taxonomyText4: $data['Taxonomy_Text_4'], + taxonomyText5: $data['Taxonomy_Text_5'], + taxonomyText6: $data['Taxonomy_Text_6'], + taxonomyURL1: $data['Taxonomy_URL_1'], + taxonomyURL2: $data['Taxonomy_URL_2'], + taxonomyURL3: $data['Taxonomy_URL_3'], + taxonomyURL4: $data['Taxonomy_URL_4'], + taxonomyURL5: $data['Taxonomy_URL_5'], + taxonomyURL6: $data['Taxonomy_URL_6'], + isHomePage: $data['homepageTest'], + toggleURL: $toggleURL ?? 'None', + hasBenefitCategory: $data['hasBenefitCategory'] ? '1' : '', + benefitCategories: $data['benefitCategories'] ?? '', + ); + } + + public static function datalayerForWizard(array $data, Term $term, string $baseURL): self { + if ($heading = $term->get('field_heading')->getValue()) { + $title = $heading[0]['value']; + } + else { + $title = $term->getName(); + } + + $friendlyURL = $term->toUrl('canonical', + options: ['language' => $term->language()] + )->toString(); + $fullURL = $term->toUrl( + options: ['absolute' => TRUE, 'language' => $term->language()] + )->toString(); + + $toggleURL = 'None'; + if (isset($term->field_language_toggle[0])) { + $toggleTerm = \Drupal::entityTypeManager() + ->getStorage('taxonomy_term') + ->load($term->field_language_toggle[0]->target_id); + $url = Url::fromRoute( + 'entity.taxonomy_term.canonical', + ['taxonomy_term' => $toggleTerm->id()], + ['absolute' => TRUE, 'language' => $toggleTerm->language()] + ); + $toggleURL = $url->toString(); + } + return new self( + hierarchy: self::getHierarchy($data), + pageType: $data['Page_Type'], + pageSubType: $data['basicPagesubType'], + contentType: $data['contentType'], + friendlyURL: $friendlyURL, + pageID: 't_' . $data['taxonomyID'], + pageTitle: $title, + fullURL: $fullURL, + taxonomyText1: self::getTaxLevel1($term->language()), + taxonomyText2: $data['Taxonomy_Text_2'], + taxonomyText3: $data['Taxonomy_Text_3'], + taxonomyText4: $data['Taxonomy_Text_4'], + taxonomyText5: $data['Taxonomy_Text_5'], + taxonomyText6: $data['Taxonomy_Text_6'], + taxonomyURL1: $data['Taxonomy_URL_1'], + taxonomyURL2: $data['Taxonomy_URL_2'], + taxonomyURL3: $data['Taxonomy_URL_3'], + taxonomyURL4: $data['Taxonomy_URL_4'], + taxonomyURL5: $data['Taxonomy_URL_5'], + taxonomyURL6: $data['Taxonomy_URL_6'], + isHomePage: $data['homepageTest'], + toggleURL: $toggleURL, + hasBenefitCategory: $data['hasBenefitCategory'] ? '1' : '', + benefitCategories: $data['benefitCategories'] ?? '', + ); + } + +} diff --git a/web/modules/custom/usagov_ssg_postprocessing/src/Drush/Commands/PublishedPagesCommands.php b/web/modules/custom/usagov_ssg_postprocessing/src/Drush/Commands/PublishedPagesCommands.php new file mode 100644 index 0000000000..66cad179f8 --- /dev/null +++ b/web/modules/custom/usagov_ssg_postprocessing/src/Drush/Commands/PublishedPagesCommands.php @@ -0,0 +1,238 @@ +get('entity_type.manager'), + configFactory: $container->get('config.factory'), + dispatcher: $container->get('event_dispatcher'), + request: $container->get('request_stack')->getCurrentRequest(), + router: $container->get('router.no_access_checks'), + pathAliasManager: $container->get('path_alias.manager'), + breadcrumb: $container->get('breadcrumb'), + languageManager: $container->get('language_manager') + ); + } + + /** + * Export published pages CSV + */ + #[CLI\Command(name: 'usagov:published-csv', aliases: ['usapubcsv'])] + #[CLI\Argument(name: 'outfile', description: 'Path for output file')] + #[CLI\Usage( + name: 'usagov_ssg_postprocessing:published-csv', + description: 'Usage description') + ] + public function publishedCsv($outfile) { + $this->output()->writeln('Publishing CSV to ' . $outfile . ''); + + $out = fopen($outfile, 'w'); + + if (!str_starts_with($outfile, '/')) { + $this->logger()->warning('Relative path given, current working dir: {dir}', ['dir' => getcwd()]); + + } + if (FALSE === $out) { + $this->output()->writeln("Can not write to destination file."); + exit(1); + } + fputcsv($out, $this->csvHeader); + // Render published pages to output file + $this->saveNodeRows($out); + $this->saveWizardRows($out); + fclose($out); + } + + protected function saveNodeRows($out): void { + $nids = $this->entityTypeManager + ->getStorage('node') + ->getQuery() + ->condition('type', [ + 'basic_page', + 'bears_life_event', + 'directory_record', + 'federal_directory_index', + 'state_directory_record', + 'wizard_step', + ], 'IN') + ->condition('status', 1) //published + ->sort('nid', 'ASC') + ->accessCheck(TRUE) + ->sort('nid') + ->execute(); + + foreach ($nids as $nid) { + $node = $this->entityTypeManager->getStorage('node')->load($nid); + $row = $this->getNodeRow($node)->toArray(); + + $row = array_map(fn($col) => trim($col), $row); + fputcsv($out, $row); + + $origLanguage = $node->language(); + if ($languages = $node->getTranslationLanguages()) { + foreach ($languages as $lang) { + if ($lang->getId() !== $origLanguage->getId()) { + // export translated node + $trNode = $node->getTranslation($lang->getId()); + $trRow = $this->getNodeRow($trNode); + $fields = array_map(fn($field) => trim($field), $trRow->toArray()); + fputcsv($out, $fields); + } + } + } + } + } + + protected function saveWizardRows($out): void { + $tids = $this->entityTypeManager + ->getStorage('taxonomy_term') + ->getQuery() + ->condition('vid', 'wizard') + ->condition('status', 1) //published + ->sort('tid', 'ASC') + ->accessCheck(TRUE) + ->sort('tid') + ->execute(); + + foreach ($tids as $tid) { + $wizard = $this->entityTypeManager->getStorage('taxonomy_term')->load($tid); + $row = $this->getWizardRow($wizard); + fputcsv($out, $row->toArray()); + } + } + + protected function getNodeRow(Node $node): PublishedPagesRow { + $front_uri = $this->configFactory->get('system.site')->get('page.front'); + $alias = $this->pathAliasManager->getAliasByPath('/node/' . $node->id()); + + $isFront = ($alias === $front_uri); + + $pageType = usa_twig_vars_get_page_type($node); + + // The following is "dragons abound here" but Drupal does not make it possible + // to change the language for building breadcrumbs after a request has started. + $negotiatedProp = new \ReflectionProperty(get_class($this->languageManager), 'negotiatedLanguages'); + $value = $negotiatedProp->getValue($this->languageManager); + $value['language_content'] = $node->language(); + $negotiatedProp->setValue($this->languageManager, $value); + + // To get the right breadcrumb/active trail for this routeMatch, the menu_breadcrumb module + // must be configured to "Derive MenuActiveTrail from RouteMatch" + $datalayer = new TaxonomyDatalayerBuilder( + routeMatch: $this->getRouteMatchForNode($node), + breadcrumbManager: $this->breadcrumb, + node: $node, + isFront: $isFront, + basicPagesubType: $pageType ?? NULL, + ); + $data = $datalayer->build(); + + $data = $this->alterDatalayer($data); + + $baseURL = $this->request->getSchemeAndHttpHost(); + return PublishedPagesRow::datalayerForNode($data, $node, $baseURL); + } + + /** + * Get a valid routeMatch object for a node + * + * To get the same datalayer output, we need to set up a routeMatch for each + * entity we are exporting that the datalayer module can look up via the + * breadcrumb manager. + */ + private function getRouteMatchForNode(Node $node): RouteMatchInterface { + $route = $this->router->match('/node/' . $node->id()); + + return new RouteMatch( + route_name: $route['_route'], + route: $route['_route_object'], + parameters: ['node' => $node], + raw_parameters: ['node' => $node->id(), 'language' => $node->language()->getId()] + ); + } + + protected function getWizardRow(Term $wizard): PublishedPagesRow { + $builder = new WizardDataLayer($wizard, $this->entityTypeManager); + $data = $builder->getData([]); + + $baseURL = $this->request->getSchemeAndHttpHost(); + return PublishedPagesRow::datalayerForWizard($data, $wizard, $baseURL); + } + + private function alterDatalayer(array $data): array { + // Let other modules add to the datalayer payload. + $datalayerEvent = new DatalayerAlterEvent($data); + $this->dispatcher->dispatch($datalayerEvent, DatalayerAlterEvent::EVENT_NAME); + return $datalayerEvent->datalayer; + } + +} diff --git a/web/modules/custom/usagov_ssg_postprocessing/src/EventSubscriber/PublishedPagesSubscriber.php b/web/modules/custom/usagov_ssg_postprocessing/src/EventSubscriber/PublishedPagesSubscriber.php deleted file mode 100644 index 1818ed91d5..0000000000 --- a/web/modules/custom/usagov_ssg_postprocessing/src/EventSubscriber/PublishedPagesSubscriber.php +++ /dev/null @@ -1,259 +0,0 @@ -getHtml(); - - // LIBXML_SCHEMA_CREATE fixes a problem wherein DOMDocument would remove closing HTML - // tags within quoted text in a script element. See https://bugs.php.net/bug.php?id=74628 - $document = new \DOMDocument(); - @$document->loadHTML($html, LIBXML_SCHEMA_CREATE); - $xpath = new \DOMXPath($document); - - $csv_path = "modules/custom/usagov_ssg_postprocessing/files/published-pages.csv"; - $csv = []; - $fp = fopen($csv_path, 'c+'); - if ($fp != FALSE) { - flock($fp, LOCK_EX); - while (($line = fgetcsv($fp)) != FALSE) { - $csv[] = $line; - } - } - - // Set the pointer to the end of the array by default. - end($csv); - $pointer = (key($csv) == FALSE) ? 0 : key($csv) + 1; - - /** @var \DOMElement $node */ - foreach ($xpath->query('/html/head/script[contains(@id, "taxonomy-data")]') as $node) { - $script = $node->nodeValue; - $script = trim($script); - $script = ltrim($script, "dataLayer = "); - $script = rtrim($script, ";"); - $script = rtrim($script, ","); - // The following line prevents json_decode() from failing when there is an extra comma after the final element in an array. - $script = str_replace(",\n }", "\n }", $script); - $decoded = json_decode($script, TRUE); - $decoded = $decoded[0]; - if (empty($decoded)) { - print "WARNING: PublishedPagesSubscriber.php is skiping a page due to a bad dataLayer\n"; - continue; - } - - $url_replace = [ - "Taxonomy_URL_1", - "Taxonomy_URL_2", - "Taxonomy_URL_3", - "Taxonomy_URL_4", - "Taxonomy_URL_5", - "Taxonomy_URL_6" - ]; - - $header_replace = [ - "nodeID" => "Page ID", - "taxonomyID" => "Page ID", - "language" => "Taxonomy Level 1", - "Taxonomy_Text_2" => "Taxonomy Level 2", - "Taxonomy_Text_3" => "Taxonomy Level 3", - "Taxonomy_Text_4" => "Taxonomy Level 4", - "Taxonomy_Text_5" => "Taxonomy Level 5", - "Taxonomy_Text_6" => "Taxonomy Level 6", - "Taxonomy_URL_1" => "Taxonomy URL Level 1", - "Taxonomy_URL_2" => "Taxonomy URL Level 2", - "Taxonomy_URL_3" => "Taxonomy URL Level 3", - "Taxonomy_URL_4" => "Taxonomy URL Level 4", - "Taxonomy_URL_5" => "Taxonomy URL Level 5", - "Taxonomy_URL_6" => "Taxonomy URL Level 6", - "Page_Type" => "Page Type", - "basicPagesubType" => "Page Sub Type", - "contentType" => "Content Type", - - "homepageTest" => "Homepage?", - ]; - - $content_replace = [ - "en" => "USAGov English", - "es" => "USAGov Español", - ]; - - $order_map = [ - "Hierarchy Level", - "Page Type", - "Page Sub Type", - "Content Type", - "Friendly URL", - "Page ID", - "Page Title", - "Full URL", - "Taxonomy Level 1", - "Taxonomy Level 2", - "Taxonomy Level 3", - "Taxonomy Level 4", - "Taxonomy Level 5", - "Taxonomy Level 6", - "Taxonomy URL Level 1", - "Taxonomy URL Level 2", - "Taxonomy URL Level 3", - "Taxonomy URL Level 4", - "Taxonomy URL Level 5", - "Taxonomy URL Level 6", - "Homepage?", - "Toggle URL", - ]; - - // If the nodeID matches a line in the csv array, set the pointer to that element. - // TODO: this might be fragile. - if (!empty($csv)) { - $nodeIDElement = array_search("Page ID", $csv[0]); - $languageElement = array_search("Taxonomy Level 1", $csv[0]); - foreach ($csv as $key => $line) { - - if (!empty($line[$nodeIDElement]) && !empty($decoded["nodeID"]) && $line[$nodeIDElement] == $decoded["nodeID"]) { - if ($line[$languageElement] == $content_replace[$decoded["language"]]) { - $pointer = $key; - } - } - - if (!empty($line[$nodeIDElement]) && !empty($decoded["taxonomyID"]) && $line[$nodeIDElement] == 't_' . $decoded["taxonomyID"]) { - if ($line[$languageElement] == $content_replace[$decoded["language"]]) { - $pointer = $key; - } - } - } - } - - $host = \Drupal::request()->getSchemeAndHttpHost(); - - $title = $xpath->query('/html/head/title')->item(0)->nodeValue; - $title = (!empty($title)) ? str_replace(" | USAGov", "", $title) : "Not Found"; - - $decoded["Page Title"] = $title; - - $toggle_url = $xpath->query('/html/head/link[contains(@data-type, "altlang")]/@href')->item(0)->nodeValue; - $decoded["Toggle URL"] = ($toggle_url) ? $toggle_url : "None"; - - $hierarchy = 0; - $prev = ""; - foreach ($decoded as $key => $term) { - if (in_array($key, $url_replace)) { - if ($term != $prev) { - $hierarchy++; - $prev = $term; - } - } - } - $decoded["Hierarchy Level"] = $hierarchy; - - $url = ""; - foreach ($decoded as $name => $term) { - if ($name == "Taxonomy_Text_1") { - unset($decoded[$name]); - } - if ($name == "Taxonomy_URL_6") { - $url = $term; - } - if ($name == "language") { - $term = $content_replace[$term]; - } - foreach ($header_replace as $key => $item) { - if ($name == $key) { - if ($name == 'taxonomyID') { - $decoded[$item] = 't_' . $term; - } - else { - $decoded[$item] = $term; - } - unset($decoded[$name]); - } - } - } - // Tome can end up requesting existing URLs with the raw `/node/NID` path - // if a redirect to a node is set to the wrong language. It then proceeds - // which retrieves the wrong taxonomy info, which we should discard. - if (str_starts_with($url, '/node/') || str_starts_with($url, '/es/node/')) { - if ($fp != FALSE) { - fclose($fp); - } - return; - } - - // If this page is more than 5 levels deep in the taxonomy hierarchy, - // Then we may not be able to reconstruct its URL from the taxonomy URL. - // We can get reliably get it from the node. We could do this for all - // nodes, but that could negatively impact export performance. - if ($decoded['Page ID'] && $hierarchy > 5) { - $nid = $decoded['Page ID']; - if (!empty($nid)) { - if (substr($nid, 0, 2) === 't_') { - $tid = intval(substr($nid, 2)); - $termEntity = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->load($tid); - if (!empty($termEntity)) { - $url = $termEntity->toUrl()->toString(); - } - } - else { - $nodeEntity = \Drupal::entityTypeManager()->getStorage('node')->load($nid); - if (!empty($nodeEntity)) { - $url = $nodeEntity->toUrl()->toString(); - } - } - } - } - - $decoded["Friendly URL"] = (empty($url)) ? "/" : $url; - $decoded["Full URL"] = (empty($url)) ? $host . "/" : $host . $url; - - $orderedArray = array_merge(array_flip($order_map), $decoded); - - if (empty($csv)) { - foreach ($orderedArray as $name => $term) { - $csvheader[] = $name; - } - $csv[$pointer] = $csvheader; - $pointer++; - } - - foreach ($orderedArray as $name => $term) { - $csvline[] = $term; - } - - $csv[$pointer] = $csvline; - - if ($fp != FALSE) { - ftruncate($fp, 0); - rewind($fp); - foreach ($csv as $fields) { - fputcsv($fp, $fields); - } - fclose($fp); - } - } - } - - /** - * {@inheritdoc} - */ - public static function getSubscribedEvents() { - $events[TomeStaticEvents::MODIFY_HTML][] = ['modifyHtml']; - return $events; - } - -} diff --git a/web/modules/custom/usagov_ssg_postprocessing/usagov_ssg_postprocessing.routing.yml b/web/modules/custom/usagov_ssg_postprocessing/usagov_ssg_postprocessing.routing.yml index 55363e08b3..bbaeaa631f 100644 --- a/web/modules/custom/usagov_ssg_postprocessing/usagov_ssg_postprocessing.routing.yml +++ b/web/modules/custom/usagov_ssg_postprocessing/usagov_ssg_postprocessing.routing.yml @@ -15,21 +15,21 @@ usagov_ssg_postprocessing.toggle_tome: _permission: 'administer site configuration' usagov_ssg_postprocessing.content: - path: '/static-site-status' - defaults: - _controller: '\Drupal\usagov_ssg_postprocessing\Controller\SsgStatController::content' + path: '/static-site-status' + defaults: + _controller: '\Drupal\usagov_ssg_postprocessing\Controller\SsgStatController::content' _title: 'Tome Status' options: no_cache: 'TRUE' - requirements: - _permission: 'access administration pages' + requirements: + _permission: 'access administration pages' usagov_ssg_postprocessing.site_lag_test: - path: '/site-lag-test' - defaults: - _controller: '\Drupal\usagov_ssg_postprocessing\Controller\SsgStatController::siteLagTest' + path: '/site-lag-test' + defaults: + _controller: '\Drupal\usagov_ssg_postprocessing\Controller\SsgStatController::siteLagTest' _title: 'Tome Status' options: no_cache: 'TRUE' - requirements: + requirements: _permission: 'access administration pages' diff --git a/web/modules/custom/usagov_ssg_postprocessing/usagov_ssg_postprocessing.services.yml b/web/modules/custom/usagov_ssg_postprocessing/usagov_ssg_postprocessing.services.yml index 564929322a..42ab4a2e4e 100644 --- a/web/modules/custom/usagov_ssg_postprocessing/usagov_ssg_postprocessing.services.yml +++ b/web/modules/custom/usagov_ssg_postprocessing/usagov_ssg_postprocessing.services.yml @@ -8,10 +8,6 @@ services: class: '\Drupal\usagov_ssg_postprocessing\EventSubscriber\PagerPathSubscriber' tags: - { name: 'event_subscriber' } - usagov_ssg_postprocessing_published_pages_events_subscriber: - class: '\Drupal\usagov_ssg_postprocessing\EventSubscriber\PublishedPagesSubscriber' - tags: - - { name: 'event_subscriber' } usagov_ssg_postprocessing_request_prepare_events_subscriber: class: '\Drupal\usagov_ssg_postprocessing\EventSubscriber\RequestPrepareSubscriber' arguments: ['@path_alias.manager', '@entity_type.manager', '@current_route_match'] diff --git a/web/modules/custom/usagov_wizard/src/EventSubscriber/DatalayerAlterSubscriber.php b/web/modules/custom/usagov_wizard/src/EventSubscriber/DatalayerAlterSubscriber.php index 8210c7f883..12485e9e8b 100644 --- a/web/modules/custom/usagov_wizard/src/EventSubscriber/DatalayerAlterSubscriber.php +++ b/web/modules/custom/usagov_wizard/src/EventSubscriber/DatalayerAlterSubscriber.php @@ -5,10 +5,9 @@ use Drupal\Core\Breadcrumb\BreadcrumbManager; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Routing\CurrentRouteMatch; -use Drupal\Core\Url; -use Drupal\taxonomy\Entity\Term; use Drupal\usa_twig_vars\Event\DatalayerAlterEvent; use Drupal\usagov_wizard\MenuChecker; +use Drupal\usagov_wizard\WizardDataLayer; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** @@ -41,97 +40,8 @@ public function onDatalayerAlter(DatalayerAlterEvent $event): void { return; } - $termStorage = $this->entityTypeManager->getStorage('taxonomy_term'); - - $isStartPage = FALSE; - $children = $termStorage->loadChildren($term->id()); - $isResult = empty($children); - - if ($term->hasField('parent')) { - $parentTID = $term->parent->getValue()[0]['target_id']; - if ($parentTID === '0') { - $isStartPage = TRUE; - } - } - - if ($isStartPage) { - $page_type = 'wizard-start'; - } - elseif ($isResult) { - $page_type = 'wizard-result'; - } - else { - $page_type = 'wizard-question'; - } - - // keep the same order - unset($event->datalayer['hasBenefitCategory']); - // make any changes need to $event->datalayer array - $event->datalayer['taxonomyID'] = $term->id(); - $event->datalayer['contentType'] = $term->bundle(); - $event->datalayer['language'] = $term->language()->getId(); - $event->datalayer['homepageTest'] = 'not_homepage'; - $event->datalayer['basicPagesubType'] = NULL; - $event->datalayer['Page_Type'] = $page_type; - $event->datalayer['hasBenefitCategory'] = FALSE; - - $rootTerm = NULL; - $parents = []; - if ($term->hasField('parent') && !$term->get('parent')->isEmpty()) { - $parents = $this->entityTypeManager - ->getStorage('taxonomy_term') - ->loadAllParents($term->id()); - // Sort parents so "oldest ancestor" is first. - $parents = array_reverse($parents); - $rootTerm = $parents[array_key_first($parents)]; - } - - if ($rootTerm) { - $crumbs = usagov_wizard_get_term_breadcrumb($rootTerm); - // Here the first two items will give us the home page - // and the main scam page - $crumbs = array_slice($crumbs, 0, 2); - foreach ($crumbs as $crumb) { - $data[$crumb['url']] = $crumb['text']; - } - } - - // the rest comes from the parents of this term - foreach ($parents as $parentTerm) { - $path = $parentTerm->get('path'); - $termURL = $path->alias; - // pathalias field items don't prepend the language code for Spanish terms - if ($parentTerm->language()->getId() === 'es') { - $termURL = '/es' . $termURL; - } - $data[$termURL] = $parentTerm->getName(); - } - - $count = count($data); - - $i = 0; - foreach ($data as $url => $text) { - $i++; - $urls['Taxonomy_Text_' . $i] = $text; - $urls['Taxonomy_URL_' . $i] = $url; - - if ($i === 6) { - break; - } - } - - if ($i < 6) { - $lastURL = array_key_last($data); - $lastText = $data[$lastURL]; - - for ($i = $count; $i < 6; $i++) { - $urls['Taxonomy_Text_' . ($i + 1)] = $lastText; - $urls['Taxonomy_URL_' . ($i + 1)] = $lastURL; - } - } - - ksort($urls); - $event->datalayer = array_merge($event->datalayer, $urls); + $builder = new WizardDataLayer($term, $this->entityTypeManager); + $event->datalayer = $builder->getData($event->datalayer); } } diff --git a/web/modules/custom/usagov_wizard/src/WizardDataLayer.php b/web/modules/custom/usagov_wizard/src/WizardDataLayer.php new file mode 100644 index 0000000000..a3cb507815 --- /dev/null +++ b/web/modules/custom/usagov_wizard/src/WizardDataLayer.php @@ -0,0 +1,113 @@ +typeManager->getStorage('taxonomy_term'); + + $isStartPage = FALSE; + $children = $termStorage->loadChildren($this->term->id()); + $isResult = empty($children); + + if ($this->term->hasField('parent')) { + $parentTID = $this->term->parent->getValue()[0]['target_id']; + if ($parentTID === '0') { + $isStartPage = TRUE; + } + } + + if ($isStartPage) { + $page_type = 'wizard-start'; + } + elseif ($isResult) { + $page_type = 'wizard-result'; + } + else { + $page_type = 'wizard-question'; + } + + // keep the same order + unset($data['hasBenefitCategory']); + // make any changes need to $event->datalayer array + $data['taxonomyID'] = $this->term->id(); + $data['contentType'] = $this->term->bundle(); + $data['language'] = $this->term->language()->getId(); + $data['homepageTest'] = 'not_homepage'; + $data['basicPagesubType'] = NULL; + $data['Page_Type'] = $page_type; + $data['hasBenefitCategory'] = FALSE; + + $rootTerm = NULL; + $parents = []; + if ( + $this->term->hasField('parent') + && !$this->term->get('parent')->isEmpty() + ) { + $parents = $this->typeManager + ->getStorage('taxonomy_term') + ->loadAllParents($this->term->id()); + // Sort parents so "oldest ancestor" is first. + $parents = array_reverse($parents); + $rootTerm = $parents[array_key_first($parents)]; + } + + if ($rootTerm) { + $crumbs = usagov_wizard_get_term_breadcrumb($rootTerm); + // Here the first two items will give us the home page + // and the main scam page + $crumbs = array_slice($crumbs, 0, 2); + foreach ($crumbs as $crumb) { + $raw[$crumb['url']] = $crumb['text']; + } + } + + // the rest comes from the parents of this term + foreach ($parents as $parentTerm) { + $path = $parentTerm->get('path'); + $termURL = $path->alias; + // pathalias field items don't prepend the language code for Spanish terms + if ($parentTerm->language()->getId() === 'es') { + $termURL = '/es' . $termURL; + } + $raw[$termURL] = $parentTerm->getName(); + } + + $count = count($raw); + + $i = 0; + foreach ($raw as $url => $text) { + $i++; + $urls['Taxonomy_Text_' . $i] = $text; + $urls['Taxonomy_URL_' . $i] = $url; + + if ($i === 6) { + break; + } + } + + if ($i < 6) { + $lastURL = array_key_last($raw); + $lastText = $raw[$lastURL]; + + for ($i = $count; $i < 6; $i++) { + $urls['Taxonomy_Text_' . ($i + 1)] = $lastText; + $urls['Taxonomy_URL_' . ($i + 1)] = $lastURL; + } + } + + ksort($urls); + return array_merge($data, $urls); + } + +} diff --git a/web/modules/custom/usagov_wizard/usagov_wizard.module b/web/modules/custom/usagov_wizard/usagov_wizard.module index 7f3cf97fe0..195d8532de 100644 --- a/web/modules/custom/usagov_wizard/usagov_wizard.module +++ b/web/modules/custom/usagov_wizard/usagov_wizard.module @@ -411,6 +411,12 @@ function usagov_wizard_get_term_breadcrumb(Term $rootTerm): array { foreach ($crumbs as $crumb) { if (isset($crumb['uri'])) { $crumb['url'] = Url::fromUri($crumb['uri'])->toString(); + // Sometimes Drupal doesn't prepend Spanish path prefix. + // Sometimes this crumb's uri is "route:" and the url is an empty string; + // in that case we should leave it empty (current page, not to be linked). + if ($crumb['url'] && $rootTerm->language()->getId() === 'es' && !str_starts_with($crumb['url'], '/es/')) { + $crumb['url'] = '/es' . $crumb['url']; + } } if (isset($crumb['title'])) { $crumb['text'] = ($crumb['title']); diff --git a/web/themes/custom/usagov/sass/_uswds-theme-custom-styles.scss b/web/themes/custom/usagov/sass/_uswds-theme-custom-styles.scss index 2db0e78830..971137b756 100644 --- a/web/themes/custom/usagov/sass/_uswds-theme-custom-styles.scss +++ b/web/themes/custom/usagov/sass/_uswds-theme-custom-styles.scss @@ -924,3 +924,12 @@ input::-webkit-textfield-decoration-container { max-width: 100%; } } + +/* Dialog sizing code for USAGOV-150 */ +.ui-dialog.ckeditor5-paragraph-embed-modal { + top: 5vh !important; + min-height: 80vh !important; +} +.ui-dialog.ckeditor5-paragraph-embed-modal > .ui-dialog-content { + height: 80vh !important; +} diff --git a/web/themes/custom/usagov/scripts/ceoResults.js b/web/themes/custom/usagov/scripts/ceoResults.js index 28bbf85488..ba854d9484 100644 --- a/web/themes/custom/usagov/scripts/ceoResults.js +++ b/web/themes/custom/usagov/scripts/ceoResults.js @@ -37,6 +37,10 @@ function lookup(address, callback) { function renderResults(response, rawResponse) { "use strict"; + // Allow the interface to show now that we are about to have content on the page + jQuery('.usa-prose-container').show(); + jQuery('.usa-prose-loader').hide(); + // Text strings for the page's language should be assigned to "usagovCEOtext" in // an inline script in the page's Header HTML. The translations here are retained for backward compatibility. const backupTranslations = { @@ -133,6 +137,7 @@ function renderResults(response, rawResponse) { h1.innerHTML = content[""+errorType+"-heading"]; resultsSection.innerHTML = ""; intro.innerHTML = content[errorType]; + intro.style.paddingBottom = '20px'; dataLayer.push({ 'event': 'CEO API Error', 'error type': errorType, @@ -465,10 +470,12 @@ function resubmitForm() { var inputStreet = localStorage.getItem("uspsStreetAddress"); var inputCity = localStorage.getItem("uspsCity"); + var inputState = localStorage.getItem("uspsState"); var inputZip = localStorage.getItem("uspsZipCode"); searchParams.set('input-street', inputStreet); searchParams.set('input-city', inputCity); + searchParams.set('input-state', inputState); searchParams.set('input-zip', inputZip); window.location.search = searchParams.toString(); @@ -483,7 +490,7 @@ function load() { let inputStreet = searchParams.get('input-street'); let inputCity = searchParams.get('input-city'); - let inputState = searchParams.get('select-dropdown'); + let inputState = searchParams.get('input-state'); let inputZip = searchParams.get('input-zip'); let normalizedAddress = inputStreet + ", " + inputCity + ", " + inputState + " " + inputZip; diff --git a/web/themes/custom/usagov/scripts/ceoSubmission.js b/web/themes/custom/usagov/scripts/ceoSubmission.js index e9972da11b..d0e8b80702 100644 --- a/web/themes/custom/usagov/scripts/ceoSubmission.js +++ b/web/themes/custom/usagov/scripts/ceoSubmission.js @@ -190,6 +190,7 @@ function uspsResponseParser(responseText, userStreetAddress, userCity, userZipCo let uspsStreetAddress = responseText.slice(responseText.indexOf('') + 10, responseText.indexOf('')); let uspsZipCode = responseText.slice(responseText.indexOf('') + 6, responseText.indexOf('')); let uspsCity = responseText.slice(responseText.indexOf('') + 6, responseText.indexOf('')); + let uspsState = responseText.slice(responseText.indexOf('') + 7, responseText.indexOf('')); // Checks if the address suggested by the USPS API is different from the user's address. // If it's different, it returns the USPS address in the response @@ -199,6 +200,7 @@ function uspsResponseParser(responseText, userStreetAddress, userCity, userZipCo response.streetAddress = uspsStreetAddress; response.city = uspsCity; + response.state = uspsState; response.zipCode = uspsZipCode; } } @@ -360,12 +362,14 @@ async function handleFormSubmission() { // Stores the suggested address for the address suggestion alert box. localStorage.setItem("uspsStreetAddress", response.streetAddress); localStorage.setItem("uspsCity", response.city); + localStorage.setItem("uspsState", response.state); localStorage.setItem("uspsZipCode", response.zipCode); localStorage.setItem("formResubmitted", false); } else { localStorage.removeItem("uspsStreetAddress"); localStorage.removeItem("uspsCity"); + localStorage.removeItem("uspsState"); localStorage.removeItem("uspsZipCode"); localStorage.removeItem("formResubmitted"); } @@ -393,7 +397,7 @@ window.addEventListener("load", function () { let isChromeOrEdge = navigator.userAgent.includes("Chrome"); // Change attributes so that autofill works in state input if (isChromeOrEdge) { - let stateSelectBox = document.getElementsByName("select-dropdown")[0]; + let stateSelectBox = document.getElementsByName("input-state")[0]; stateSelectBox.setAttribute("autocomplete","country"); let stateInputBox = document.getElementById("input-state"); diff --git a/web/themes/custom/usagov/templates/field--node--field-custom-twig-content-elected-officials-results.html.twig b/web/themes/custom/usagov/templates/field--node--field-custom-twig-content-elected-officials-results.html.twig index cb559105b4..1f8eadc416 100644 --- a/web/themes/custom/usagov/templates/field--node--field-custom-twig-content-elected-officials-results.html.twig +++ b/web/themes/custom/usagov/templates/field--node--field-custom-twig-content-elected-officials-results.html.twig @@ -1,20 +1,28 @@ -
-

Your address:

-
-

- Street Address
- City, State, Zip -

+
+
+
Loading results...
+
+ + +
diff --git a/web/themes/custom/usagov/templates/field--node--field-custom-twig-content-elected-officials.html.twig b/web/themes/custom/usagov/templates/field--node--field-custom-twig-content-elected-officials.html.twig index 3be8874946..1f8a3dd544 100644 --- a/web/themes/custom/usagov/templates/field--node--field-custom-twig-content-elected-officials.html.twig +++ b/web/themes/custom/usagov/templates/field--node--field-custom-twig-content-elected-officials.html.twig @@ -85,7 +85,7 @@