From 078cd32fc2a3a6fd97728097f83e7bb5d81d3e7c Mon Sep 17 00:00:00 2001 From: Andrew Pasquale Date: Tue, 19 Aug 2025 15:47:25 -0400 Subject: [PATCH 01/11] Add PHPStan linting and pre-commit hook - Add phpstan.neon configuration for static analysis - Add pre-commit hook to check staged PHP files - Configured to use main project's vendor directory - Level 5 analysis for good balance of strictness --- phpstan.neon | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 phpstan.neon diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 00000000..cca2f520 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,15 @@ +parameters: + level: 5 + paths: + - . + excludePaths: + - tests/* + - */tests/* + - vendor/* + # Point to parent Drupal installation for context + scanDirectories: + - ../../../../core + - ../../../../modules/contrib + ignoreErrors: + - identifier: missingType.iterableValue + - identifier: missingType.generics From e79cf8c82cf0f1588f055f2e41757701b5f35643 Mon Sep 17 00:00:00 2001 From: Andrew Pasquale Date: Tue, 19 Aug 2025 17:18:09 -0400 Subject: [PATCH 02/11] Fix PHPStan script with absolute paths for pre-commit compatibility --- .pre-commit-config.yaml | 9 ++ .../access_llm/src/AiReferenceGenerator.php | 113 +----------------- scripts/run-phpstan.sh | 35 ++++++ 3 files changed, 45 insertions(+), 112 deletions(-) create mode 100644 .pre-commit-config.yaml create mode 100755 scripts/run-phpstan.sh diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..9c9d4527 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,9 @@ +repos: + - repo: local + hooks: + - id: phpstan + name: PHPStan + entry: ./scripts/run-phpstan.sh + language: system + files: \.(php)$ + pass_filenames: false \ No newline at end of file diff --git a/modules/access_llm/src/AiReferenceGenerator.php b/modules/access_llm/src/AiReferenceGenerator.php index 1de88180..4b0db34e 100644 --- a/modules/access_llm/src/AiReferenceGenerator.php +++ b/modules/access_llm/src/AiReferenceGenerator.php @@ -141,118 +141,7 @@ public function getBundleAiReferencesConfiguration($bundle) { return $ai_references; } - - /** - * Gets AI auto-reference suggestions. - * - * @param \Drupal\node\NodeInterface $node - * Node object. - * @param string $field_name - * Field machine name. - * @param string $view_mode - * Entity view mode. - * - * @return array - * Array with suggestions. - */ - public function getAiSuggestions(NodeInterface $node, $field_name, $view_mode) { - $config = $this->config->get('ai_auto_reference.settings'); - - try { - // Might be 4000, 8000, 32000 depending on version used and - // beta / waiting list access approval. - $token_limit = $config->get('token_limit'); - - $possible_results = $this->getFieldAllowedValues($node, $field_name); - $imploded_possible_results = implode(',', $possible_results); - - // Getting current (in most cases – admin) theme. - $active_theme = $this->themeManager->getActiveTheme(); - // Getting default theme. - $default_theme = $this->config->get('system.theme')->get('default'); - - // We need to be sure we render content in default theme. - $this->themeManager->setActiveTheme($this->themeInitialization->initTheme($default_theme)); - $render_controller = $this->entityTypeManager->getViewBuilder($node->getEntityTypeId()); - - // Get the rendered contents of the node. - $render_output = $render_controller->view($node, $view_mode); - $rendered_output = $this->renderer->renderPlain($render_output); - $contents = strip_tags($rendered_output); - - // Switching back to admin theme. - $this->themeManager->setActiveTheme($active_theme); - - // For counting the number of tokens. - $tokenizer_config = new Gpt3TokenizerConfig(); - $tokenizer = new Gpt3Tokenizer($tokenizer_config); - - // Build the prompt to send. - // @todo allow configuration of the prompt. - $prompt = 'For the contents within brackets: ({CONTENTS})'; - $prompt .= 'Which two to four of the following | separated options are highly relevant and moderately relevant? [{POSSIBLE_RESULTS}]'; - $prompt .= 'Return selections from within the square brackets only and as a valid json array within two array keys "highly" and "moderately" for your relevance'; - - // Node edit link to use in logs. - $node_edit_link = Link::fromTextAndUrl($node->label(), Url::fromRoute('entity.node.edit_form', ['node' => $node->id()]))->toString(); - - // If the prompt is longer than the limit, get a summary of the contents. - $prompt_length = $tokenizer->count($prompt); - $possible_results_length = $tokenizer->count($imploded_possible_results); - $contents_length = $tokenizer->count($contents); - if ($prompt_length + $possible_results_length > $token_limit) { - $this->logger->error('The prompt and possible results alone use more tokens than the token limit for %field_name for %node_edit. The job cannot be completed', [ - '%field_name' => $field_name, - '%node_edit' => $node_edit_link, - ]); - } - elseif ($prompt_length + $possible_results_length + $contents_length > $token_limit) { - // Make an API call to get a summary of the content. - $available_contents_tokens = $token_limit - $prompt_length - $possible_results_length; - // @todo allow configuration of the text shortening prompt. - $summary_prompt = 'Shorten this text into a maximum of ' . $available_contents_tokens . ' tokens and minimum of ' . ($available_contents_tokens - 1000) . ' tokens: '; - $summary_prompt_length = $tokenizer->count($summary_prompt); - if ($contents_length + $summary_prompt_length > $token_limit) { - - // If even this without the possible results is too long, we - // just crop it - no choice. - $content_chunks = $tokenizer->chunk($contents, ($token_limit - $summary_prompt_length)); - $contents = reset($content_chunks); - } - - // Add contents (potentially cropped) to the prompt. - $summary_prompt .= $contents; - - // Get the summary back. - $response = $this->aiApiCall($config, $summary_prompt); - if (isset($response->choices[0]->message->content)) { - // Replace the contents with summarized contents. - $contents = $response->choices[0]->message->content; - } - } - - // Run replacements in the prompt. - $prompt = str_replace('{POSSIBLE_RESULTS}', $imploded_possible_results, $prompt); - $prompt = str_replace('{CONTENTS}', $contents, $prompt); - // Get the array of 'highly' and 'moderately' related results back. - if ($answer = $this->aiApiCall($config, $prompt)) { - $answer = json_decode($answer, 1); - $suggestions['h'] = !empty($answer['highly']) ? array_keys(array_intersect($possible_results, $answer['highly'])) : []; - $suggestions['m'] = !empty($answer['moderately']) ? array_keys(array_intersect($possible_results, $answer['moderately'])) : []; - return $suggestions; - } - - } - catch (\Exception $exception) { - $this->logger->error('AI auto-reference generation failed for %field_name for %node_edit. Error message: %error_message', [ - '%field_name' => $field_name, - '%node_edit' => $node_edit_link, - '%error_message' => $exception->getMessage(), - ]); - } - // Fallback to empty array. - return []; - } + /** * diff --git a/scripts/run-phpstan.sh b/scripts/run-phpstan.sh new file mode 100755 index 00000000..986a1584 --- /dev/null +++ b/scripts/run-phpstan.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +# Get the directory where this script is located +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +# Navigate to the ACCESS module root (one level up from scripts/) +cd "$SCRIPT_DIR/.." + +# Get the absolute path to the parent Drupal installation +DRUPAL_ROOT="$(cd ../../../.. && pwd)" + +# Create a temporary phpstan config with absolute paths +cat > phpstan-tmp.neon << EOF +includes: + - phpstan-baseline.neon +parameters: + level: 0 + paths: + - . + excludePaths: + - tests/* + - */tests/* + - vendor/* + bootstrapFiles: + - $DRUPAL_ROOT/vendor/autoload.php +EOF + +# Run PHPStan with absolute paths +"$DRUPAL_ROOT/vendor/bin/phpstan" analyse \ + --configuration=phpstan-tmp.neon \ + --memory-limit=512M \ + --no-progress + +# Clean up temp config +rm -f phpstan-tmp.neon \ No newline at end of file From b79db672561b8e5ed60a768135eb9fde017b7044 Mon Sep 17 00:00:00 2001 From: Andrew Pasquale Date: Tue, 19 Aug 2025 17:19:50 -0400 Subject: [PATCH 03/11] Clean up PHPStan script - remove temporary file creation --- phpstan.neon | 11 +++-------- scripts/run-phpstan.sh | 26 ++++---------------------- 2 files changed, 7 insertions(+), 30 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index cca2f520..8ddde714 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,15 +1,10 @@ +includes: + - phpstan-baseline.neon parameters: - level: 5 + level: 0 paths: - . excludePaths: - tests/* - */tests/* - vendor/* - # Point to parent Drupal installation for context - scanDirectories: - - ../../../../core - - ../../../../modules/contrib - ignoreErrors: - - identifier: missingType.iterableValue - - identifier: missingType.generics diff --git a/scripts/run-phpstan.sh b/scripts/run-phpstan.sh index 986a1584..bd2de856 100755 --- a/scripts/run-phpstan.sh +++ b/scripts/run-phpstan.sh @@ -9,27 +9,9 @@ cd "$SCRIPT_DIR/.." # Get the absolute path to the parent Drupal installation DRUPAL_ROOT="$(cd ../../../.. && pwd)" -# Create a temporary phpstan config with absolute paths -cat > phpstan-tmp.neon << EOF -includes: - - phpstan-baseline.neon -parameters: - level: 0 - paths: - - . - excludePaths: - - tests/* - - */tests/* - - vendor/* - bootstrapFiles: - - $DRUPAL_ROOT/vendor/autoload.php -EOF - -# Run PHPStan with absolute paths +# Run PHPStan with explicit autoload file instead of using config bootstrap "$DRUPAL_ROOT/vendor/bin/phpstan" analyse \ - --configuration=phpstan-tmp.neon \ + --configuration=phpstan.neon \ + --autoload-file="$DRUPAL_ROOT/vendor/autoload.php" \ --memory-limit=512M \ - --no-progress - -# Clean up temp config -rm -f phpstan-tmp.neon \ No newline at end of file + --no-progress \ No newline at end of file From 7cba34e3212c52ea333423fcd65128453b6d4e27 Mon Sep 17 00:00:00 2001 From: Andrew Pasquale Date: Tue, 19 Aug 2025 17:24:25 -0400 Subject: [PATCH 04/11] Precommit hooks for phpstan linting and deprecation fixes --- .gitignore | 15 + composer.json | 14 + composer.lock | 994 ++++++++++++++++++ .../access_affinitygroup.module | 2 +- .../src/Commands/AffinityGroupCommands.php | 6 +- .../src/Plugin/Block/TopAskCiTags.php | 1 + modules/access_cilink/access_cilink.module | 16 +- .../src/Controller/CiLinkController.php | 8 +- modules/access_news/access_news.module | 12 +- .../WebformHandler/AccountSupportHandler.php | 3 +- .../RequestOrgsListAddHandler.php | 3 +- .../TicketingSendEmailHandler.php | 3 +- .../src/Commands/UserProfilesCommands.php | 8 +- phpstan-baseline.neon | 435 ++++++++ phpstan-simple.neon | 11 + 15 files changed, 1505 insertions(+), 26 deletions(-) create mode 100644 .gitignore create mode 100644 composer.lock create mode 100644 phpstan-baseline.neon create mode 100644 phpstan-simple.neon diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..2a50e8cb --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +# Composer dependencies +vendor/ + +# PHPStan temporary files +phpstan-tmp.neon + +# IDE files +.vscode/ +.idea/ +*.swp +*.swo + +# OS files +.DS_Store +Thumbs.db \ No newline at end of file diff --git a/composer.json b/composer.json index 75ceb716..30546b23 100644 --- a/composer.json +++ b/composer.json @@ -17,5 +17,19 @@ "support": { "issues": "https://github.com/necyberteam/access/issues", "source": "https://github.com/necyberteam/access" + }, + "require-dev": { + "phpstan/phpstan": "*", + "mglaman/phpstan-drupal": "*", + "phpstan/extension-installer": "*" + }, + "config": { + "allow-plugins": { + "phpstan/extension-installer": true + } + }, + "scripts": { + "lint": "../../../../vendor/bin/phpstan analyse --configuration=phpstan.neon --memory-limit=512M", + "lint:baseline": "../../../../vendor/bin/phpstan analyse --configuration=phpstan.neon --memory-limit=512M --generate-baseline" } } diff --git a/composer.lock b/composer.lock new file mode 100644 index 00000000..3fd28174 --- /dev/null +++ b/composer.lock @@ -0,0 +1,994 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "06bffdd15f3fc6fc2bec7f60f8734161", + "packages": [ + { + "name": "gioni06/gpt3-tokenizer", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/Gioni06/GPT3Tokenizer.git", + "reference": "86f824f0e852e6a26887dac367e03bdeed07ef42" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Gioni06/GPT3Tokenizer/zipball/86f824f0e852e6a26887dac367e03bdeed07ef42", + "reference": "86f824f0e852e6a26887dac367e03bdeed07ef42", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": "^8.0.2" + }, + "require-dev": { + "phpunit/phpunit": "^9.5.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Gioni06\\Gpt3Tokenizer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Jonas Duri", + "email": "jonas.duri@gmail.com" + } + ], + "description": "PHP package for Byte Pair Encoding (BPE) used by GPT-3.", + "homepage": "https://github.com/Gioni06/GPT3Tokenizer", + "keywords": [ + "GPT-3", + "decode", + "encode", + "gpt-2", + "openai", + "tokenizer" + ], + "support": { + "issues": "https://github.com/Gioni06/GPT3Tokenizer/issues", + "source": "https://github.com/Gioni06/GPT3Tokenizer" + }, + "time": "2023-04-16T12:49:18+00:00" + }, + { + "name": "openai-php/client", + "version": "v0.4.2", + "source": { + "type": "git", + "url": "https://github.com/openai-php/client.git", + "reference": "bbfbc0a28872d679d6990712d7feaae2c9f96fc2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/openai-php/client/zipball/bbfbc0a28872d679d6990712d7feaae2c9f96fc2", + "reference": "bbfbc0a28872d679d6990712d7feaae2c9f96fc2", + "shasum": "" + }, + "require": { + "php": "^8.1.0", + "php-http/discovery": "^1.15.3", + "php-http/multipart-stream-builder": "^1.2.0", + "psr/http-client": "^1.0.2", + "psr/http-client-implementation": "^1.0.1", + "psr/http-factory-implementation": "*", + "psr/http-message": "^1.1.0" + }, + "require-dev": { + "guzzlehttp/guzzle": "^7.5.0", + "guzzlehttp/psr7": "^2.4.4", + "laravel/pint": "^1.8.0", + "nunomaduro/collision": "^7.4.0", + "pestphp/pest": "^2.4.0", + "pestphp/pest-plugin-arch": "^2.1.1", + "pestphp/pest-plugin-mock": "^2.0.0", + "phpstan/phpstan": "^1.10.11", + "rector/rector": "^0.14.8", + "symfony/var-dumper": "^6.2.8" + }, + "type": "library", + "autoload": { + "files": [ + "src/OpenAI.php" + ], + "psr-4": { + "OpenAI\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + }, + { + "name": "Sandro Gehri" + } + ], + "description": "OpenAI PHP is a supercharged PHP API client that allows you to interact with the Open AI API", + "keywords": [ + "GPT-3", + "api", + "client", + "codex", + "dall-e", + "language", + "natural", + "openai", + "php", + "processing", + "sdk" + ], + "support": { + "issues": "https://github.com/openai-php/client/issues", + "source": "https://github.com/openai-php/client/tree/v0.4.2" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/gehrisandro", + "type": "github" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + } + ], + "time": "2023-04-12T04:26:02+00:00" + }, + { + "name": "php-http/discovery", + "version": "1.20.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/discovery.git", + "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/discovery/zipball/82fe4c73ef3363caed49ff8dd1539ba06044910d", + "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0|^2.0", + "php": "^7.1 || ^8.0" + }, + "conflict": { + "nyholm/psr7": "<1.0", + "zendframework/zend-diactoros": "*" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "*", + "psr/http-factory-implementation": "*", + "psr/http-message-implementation": "*" + }, + "require-dev": { + "composer/composer": "^1.0.2|^2.0", + "graham-campbell/phpspec-skip-example-extension": "^5.0", + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3", + "sebastian/comparator": "^3.0.5 || ^4.0.8", + "symfony/phpunit-bridge": "^6.4.4 || ^7.0.1" + }, + "type": "composer-plugin", + "extra": { + "class": "Http\\Discovery\\Composer\\Plugin", + "plugin-optional": true + }, + "autoload": { + "psr-4": { + "Http\\Discovery\\": "src/" + }, + "exclude-from-classmap": [ + "src/Composer/Plugin.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations", + "homepage": "http://php-http.org", + "keywords": [ + "adapter", + "client", + "discovery", + "factory", + "http", + "message", + "psr17", + "psr7" + ], + "support": { + "issues": "https://github.com/php-http/discovery/issues", + "source": "https://github.com/php-http/discovery/tree/1.20.0" + }, + "time": "2024-10-02T11:20:13+00:00" + }, + { + "name": "php-http/multipart-stream-builder", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/php-http/multipart-stream-builder.git", + "reference": "10086e6de6f53489cca5ecc45b6f468604d3460e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/multipart-stream-builder/zipball/10086e6de6f53489cca5ecc45b6f468604d3460e", + "reference": "10086e6de6f53489cca5ecc45b6f468604d3460e", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/discovery": "^1.15", + "psr/http-factory-implementation": "^1.0" + }, + "require-dev": { + "nyholm/psr7": "^1.0", + "php-http/message": "^1.5", + "php-http/message-factory": "^1.0.2", + "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Http\\Message\\MultipartStream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + } + ], + "description": "A builder class that help you create a multipart stream", + "homepage": "http://php-http.org", + "keywords": [ + "factory", + "http", + "message", + "multipart stream", + "stream" + ], + "support": { + "issues": "https://github.com/php-http/multipart-stream-builder/issues", + "source": "https://github.com/php-http/multipart-stream-builder/tree/1.4.2" + }, + "time": "2024-09-04T13:22:54+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-message", + "version": "1.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/1.1" + }, + "time": "2023-04-04T09:50:52+00:00" + } + ], + "packages-dev": [ + { + "name": "mglaman/phpstan-drupal", + "version": "2.0.9", + "source": { + "type": "git", + "url": "https://github.com/mglaman/phpstan-drupal.git", + "reference": "fed292ee0e3cc5b86d6f818585697022f46ade3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mglaman/phpstan-drupal/zipball/fed292ee0e3cc5b86d6f818585697022f46ade3c", + "reference": "fed292ee0e3cc5b86d6f818585697022f46ade3c", + "shasum": "" + }, + "require": { + "php": "^8.1", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-deprecation-rules": "^2.0", + "symfony/finder": "^6.2 || ^7.0", + "symfony/yaml": "^6.2 || ^7.0", + "webflo/drupal-finder": "^1.3.1" + }, + "require-dev": { + "behat/mink": "^1.10", + "composer/installers": "^1.9 || ^2", + "drupal/core-recommended": "^10", + "drush/drush": "^11 || ^12 || ^13", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9 || ^10 || ^11", + "slevomat/coding-standard": "^8.6", + "squizlabs/php_codesniffer": "^3.7", + "symfony/phpunit-bridge": "^6.2 || ^7.0" + }, + "suggest": { + "jangregor/phpstan-prophecy": "Provides a prophecy/prophecy extension for phpstan/phpstan.", + "phpstan/phpstan-deprecation-rules": "For catching deprecations, especially in Drupal core.", + "phpstan/phpstan-phpunit": "PHPUnit extensions and rules for PHPStan." + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "extension.neon", + "rules.neon" + ] + }, + "installer-paths": { + "tests/fixtures/drupal/core": [ + "type:drupal-core" + ], + "tests/fixtures/drupal/libraries/{$name}": [ + "type:drupal-library" + ], + "tests/fixtures/drupal/themes/contrib/{$name}": [ + "type:drupal-theme" + ], + "tests/fixtures/drupal/modules/contrib/{$name}": [ + "type:drupal-module" + ], + "tests/fixtures/drupal/profiles/contrib/{$name}": [ + "type:drupal-profile" + ] + } + }, + "autoload": { + "psr-4": { + "mglaman\\PHPStanDrupal\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matt Glaman", + "email": "nmd.matt@gmail.com" + } + ], + "description": "Drupal extension and rules for PHPStan", + "support": { + "issues": "https://github.com/mglaman/phpstan-drupal/issues", + "source": "https://github.com/mglaman/phpstan-drupal/tree/2.0.9" + }, + "funding": [ + { + "url": "https://github.com/mglaman", + "type": "github" + }, + { + "url": "https://opencollective.com/phpstan-drupal", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/mglaman/phpstan-drupal", + "type": "tidelift" + } + ], + "time": "2025-08-05T14:22:12+00:00" + }, + { + "name": "phpstan/extension-installer", + "version": "1.4.3", + "source": { + "type": "git", + "url": "https://github.com/phpstan/extension-installer.git", + "reference": "85e90b3942d06b2326fba0403ec24fe912372936" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/85e90b3942d06b2326fba0403ec24fe912372936", + "reference": "85e90b3942d06b2326fba0403ec24fe912372936", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0", + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.9.0 || ^2.0" + }, + "require-dev": { + "composer/composer": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2.0", + "phpstan/phpstan-strict-rules": "^0.11 || ^0.12 || ^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPStan\\ExtensionInstaller\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPStan\\ExtensionInstaller\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Composer plugin for automatic installation of PHPStan extensions", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpstan/extension-installer/issues", + "source": "https://github.com/phpstan/extension-installer/tree/1.4.3" + }, + "time": "2024-09-04T20:21:43+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "2.1.22", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "41600c8379eb5aee63e9413fe9e97273e25d57e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/41600c8379eb5aee63e9413fe9e97273e25d57e4", + "reference": "41600c8379eb5aee63e9413fe9e97273e25d57e4", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2025-08-04T19:17:37+00:00" + }, + { + "name": "phpstan/phpstan-deprecation-rules", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-deprecation-rules.git", + "reference": "468e02c9176891cc901143da118f09dc9505fc2f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-deprecation-rules/zipball/468e02c9176891cc901143da118f09dc9505fc2f", + "reference": "468e02c9176891cc901143da118f09dc9505fc2f", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0", + "phpstan/phpstan": "^2.1.15" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.6" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan rules for detecting usage of deprecated classes, methods, properties, constants and traits.", + "support": { + "issues": "https://github.com/phpstan/phpstan-deprecation-rules/issues", + "source": "https://github.com/phpstan/phpstan-deprecation-rules/tree/2.0.3" + }, + "time": "2025-05-14T10:56:57+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.6.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/finder", + "version": "v7.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "2a6614966ba1074fa93dae0bc804227422df4dfe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/2a6614966ba1074fa93dae0bc804227422df4dfe", + "reference": "2a6614966ba1074fa93dae0bc804227422df4dfe", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v7.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-15T13:41:35+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.32.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/yaml", + "version": "v7.3.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "b8d7d868da9eb0919e99c8830431ea087d6aae30" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/b8d7d868da9eb0919e99c8830431ea087d6aae30", + "reference": "b8d7d868da9eb0919e99c8830431ea087d6aae30", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/console": "<6.4" + }, + "require-dev": { + "symfony/console": "^6.4|^7.0" + }, + "bin": [ + "Resources/bin/yaml-lint" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Loads and dumps YAML files", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v7.3.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-07-10T08:47:49+00:00" + }, + { + "name": "webflo/drupal-finder", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/webflo/drupal-finder.git", + "reference": "73045060b0894c77962a10cff047f72872d8810c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webflo/drupal-finder/zipball/73045060b0894c77962a10cff047f72872d8810c", + "reference": "73045060b0894c77962a10cff047f72872d8810c", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2.2", + "php": ">=8.1" + }, + "require-dev": { + "mikey179/vfsstream": "^1.6", + "phpunit/phpunit": "^10.4", + "symfony/process": "^6.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "DrupalFinder\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0-or-later" + ], + "authors": [ + { + "name": "Florian Weber", + "email": "florian@webflo.org" + } + ], + "description": "Helper class to locate a Drupal installation.", + "support": { + "issues": "https://github.com/webflo/drupal-finder/issues", + "source": "https://github.com/webflo/drupal-finder/tree/1.3.1" + }, + "time": "2024-06-28T13:45:36+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": {}, + "prefer-stable": false, + "prefer-lowest": false, + "platform": {}, + "platform-dev": {}, + "plugin-api-version": "2.6.0" +} diff --git a/modules/access_affinitygroup/access_affinitygroup.module b/modules/access_affinitygroup/access_affinitygroup.module index b5806f79..efdeaa28 100644 --- a/modules/access_affinitygroup/access_affinitygroup.module +++ b/modules/access_affinitygroup/access_affinitygroup.module @@ -109,7 +109,7 @@ function access_affinitygroup_preprocess_views_view_field(&$variables) { $flag_ag = \Drupal::service('flag.link_builder')->build('taxonomy_term', $tid, 'affinity_group', 'full'); $flag_ag['#attributes']['class'][] = 'btn-sm btn-small btn-secondary-outline py-0 px-4'; - $flag_ag = \Drupal::service('renderer')->renderPlain($flag_ag); + $flag_ag = \Drupal::service('renderer')->renderInIsolation($flag_ag); // Attach a custom cache tag to the output. $variables['#cache']['tags'][] = 'affinity_group_field_' . $tid; diff --git a/modules/access_affinitygroup/src/Commands/AffinityGroupCommands.php b/modules/access_affinitygroup/src/Commands/AffinityGroupCommands.php index c1ddf58e..195500ec 100644 --- a/modules/access_affinitygroup/src/Commands/AffinityGroupCommands.php +++ b/modules/access_affinitygroup/src/Commands/AffinityGroupCommands.php @@ -286,7 +286,7 @@ public function showNews() { $view_builder = \Drupal::entityTypeManager()->getViewBuilder('node'); $renderArray = $view_builder->view($node, 'newsBody'); // $renderArray = $view_builder->view($node); - $display = \Drupal::service('renderer')->renderPlain($renderArray); + $display = \Drupal::service('renderer')->renderInIsolation($renderArray); $this->output()->writeln($display); $this->output()->writeln('---'); @@ -352,7 +352,7 @@ public function showEventsI() { // Get the custom view display eventinstance.email_summary $view_builder = \Drupal::entityTypeManager()->getViewBuilder('eventinstance'); $renderArray = $view_builder->view($enode, 'rollup_list'); - $display = \Drupal::service('renderer')->renderPlain($renderArray); + $display = \Drupal::service('renderer')->renderInIsolation($renderArray); // $this->output()->writeln($display); // TEMP @@ -393,7 +393,7 @@ public function showEventsS() { // $renderArray = $view_builder->view($node); // $this->output()->writeln('c-----------'); $body = ''; - // $body = \Drupal::service('renderer')->renderPlain($renderArray); + // $body = \Drupal::service('renderer')->renderInIsolation($renderArray); // $this->output()->writeln('d-----------'); // $this->output()->writeln($body); // $this->output()->writeln('e-----------'); diff --git a/modules/access_affinitygroup/src/Plugin/Block/TopAskCiTags.php b/modules/access_affinitygroup/src/Plugin/Block/TopAskCiTags.php index 8ab02f15..1e821599 100644 --- a/modules/access_affinitygroup/src/Plugin/Block/TopAskCiTags.php +++ b/modules/access_affinitygroup/src/Plugin/Block/TopAskCiTags.php @@ -11,6 +11,7 @@ use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Url; use GuzzleHttp\Client; +use GuzzleHttp\Exception\RequestException; use Symfony\Component\DependencyInjection\ContainerInterface; /** diff --git a/modules/access_cilink/access_cilink.module b/modules/access_cilink/access_cilink.module index 7e8164a8..f48d48e8 100644 --- a/modules/access_cilink/access_cilink.module +++ b/modules/access_cilink/access_cilink.module @@ -174,7 +174,7 @@ function access_cilink_preprocess_views_view_field(&$variables) { // Upvote widget. $flag_upvote = \Drupal::service('flag.link_builder')->build('webform_submission', $sid, 'upvote', 'full'); - $flag_upvote = \Drupal::service('renderer')->renderPlain($flag_upvote); + $flag_upvote = \Drupal::service('renderer')->renderInIsolation($flag_upvote); $flag_upvote = "
$flag_upvote
"; $likes_count = "$flag_upvote_count"; @@ -216,13 +216,13 @@ function access_cilink_preprocess_views_view_field(&$variables) { $flag_classes = 'no-underline text-dark-teal hover--underline'; $flag_outdated = \Drupal::service('flag.link_builder')->build('webform_submission', $sid, 'outdated', 'full'); $flag_outdated['#attributes']['class'][] = $flag_classes; - $flag_outdated = \Drupal::service('renderer')->renderPlain($flag_outdated); + $flag_outdated = \Drupal::service('renderer')->renderInIsolation($flag_outdated); $flag_not_useful = \Drupal::service('flag.link_builder')->build('webform_submission', $sid, 'not_useful', 'full'); $flag_not_useful['#attributes']['class'][] = $flag_classes; - $flag_not_useful = \Drupal::service('renderer')->renderPlain($flag_not_useful); + $flag_not_useful = \Drupal::service('renderer')->renderInIsolation($flag_not_useful); $flag_inaccurate = \Drupal::service('flag.link_builder')->build('webform_submission', $sid, 'inaccurate', 'full'); $flag_inaccurate['#attributes']['class'][] = $flag_classes; - $flag_inaccurate = \Drupal::service('renderer')->renderPlain($flag_inaccurate); + $flag_inaccurate = \Drupal::service('renderer')->renderInIsolation($flag_inaccurate); // Get full url including domain. $url = \Drupal::request()->getSchemeAndHttpHost() . '/knowledge-base/resources?f%5B0%5D=submission_id%3A' . $sid; @@ -379,13 +379,13 @@ function access_cilink_preprocess_views_view_field(&$variables) { $sid = $matches[1]; $flag_outdated = \Drupal::service('flag.link_builder')->build('webform_submission', $sid, 'outdated', 'full'); $flag_outdated['#attributes']['class'][] = 'dropdown-item'; - $flag_outdated = \Drupal::service('renderer')->renderPlain($flag_outdated); + $flag_outdated = \Drupal::service('renderer')->renderInIsolation($flag_outdated); $flag_not_useful = \Drupal::service('flag.link_builder')->build('webform_submission', $sid, 'not_useful', 'full'); $flag_not_useful['#attributes']['class'][] = 'dropdown-item'; - $flag_not_useful = \Drupal::service('renderer')->renderPlain($flag_not_useful); + $flag_not_useful = \Drupal::service('renderer')->renderInIsolation($flag_not_useful); $flag_inaccurate = \Drupal::service('flag.link_builder')->build('webform_submission', $sid, 'inaccurate', 'full'); $flag_inaccurate['#attributes']['class'][] = 'dropdown-item'; - $flag_inaccurate = \Drupal::service('renderer')->renderPlain($flag_inaccurate); + $flag_inaccurate = \Drupal::service('renderer')->renderInIsolation($flag_inaccurate); $replaced_text = "
  • $flag_outdated
  • $flag_not_useful
  • $flag_inaccurate
  • "; @@ -466,7 +466,7 @@ function access_cilink_resource_email() { '#rows' => $rows, '#attributes' => ['id' => 'ask-ci', 'class' => ['border-0']], ]; - $output = \Drupal::service('renderer')->renderPlain($html); + $output = \Drupal::service('renderer')->renderInIsolation($html); // Lookup users by role. $uids = \Drupal::entityQuery('user') diff --git a/modules/access_cilink/src/Controller/CiLinkController.php b/modules/access_cilink/src/Controller/CiLinkController.php index b59588f9..4d6f49a6 100644 --- a/modules/access_cilink/src/Controller/CiLinkController.php +++ b/modules/access_cilink/src/Controller/CiLinkController.php @@ -150,7 +150,7 @@ public function cilinks() { // Upvote widget. $flag_upvote = \Drupal::service('flag.link_builder')->build('webform_submission', $this->sid, 'upvote', 'full'); - $flag_upvote = \Drupal::service('renderer')->renderPlain($flag_upvote); + $flag_upvote = \Drupal::service('renderer')->renderInIsolation($flag_upvote); $flag_upvote_count = \Drupal::service('flag.count')->getEntityFlagCounts($this->webform_submission); $flag_upvote_set = $flag_upvote_count['upvote'] ?? 0; $flag_upvote_count = $flag_upvote_set ? $flag_upvote_count['upvote'] : 0; @@ -189,13 +189,13 @@ public function cilinks() { $flag_classes = 'no-underline text-dark-teal hover--underline'; $flag_outdated = \Drupal::service('flag.link_builder')->build('webform_submission', $this->sid, 'outdated', 'full'); $flag_outdated['#attributes']['class'][] = $flag_classes; - $flag_outdated = \Drupal::service('renderer')->renderPlain($flag_outdated); + $flag_outdated = \Drupal::service('renderer')->renderInIsolation($flag_outdated); $flag_not_useful = \Drupal::service('flag.link_builder')->build('webform_submission', $this->sid, 'not_useful', 'full'); $flag_not_useful['#attributes']['class'][] = $flag_classes; - $flag_not_useful = \Drupal::service('renderer')->renderPlain($flag_not_useful); + $flag_not_useful = \Drupal::service('renderer')->renderInIsolation($flag_not_useful); $flag_inaccurate = \Drupal::service('flag.link_builder')->build('webform_submission', $this->sid, 'inaccurate', 'full'); $flag_inaccurate['#attributes']['class'][] = $flag_classes; - $flag_inaccurate = \Drupal::service('renderer')->renderPlain($flag_inaccurate); + $flag_inaccurate = \Drupal::service('renderer')->renderInIsolation($flag_inaccurate); // Check if the user is logged in. $user = \Drupal::currentUser(); diff --git a/modules/access_news/access_news.module b/modules/access_news/access_news.module index 3cdaf0d0..2bafad97 100644 --- a/modules/access_news/access_news.module +++ b/modules/access_news/access_news.module @@ -463,7 +463,7 @@ function affinityGroupBroadcast(EntityInterface $node, $newsType) { // Body set using a custom view mode: ccemail. $view_builder = \Drupal::entityTypeManager()->getViewBuilder('eventseries'); $renderArray = $view_builder->view($node, 'ccemail'); - $body = \Drupal::service('renderer')->renderPlain($renderArray); + $body = \Drupal::service('renderer')->renderInIsolation($renderArray); $body = str_replace('Event Instances', 'Event Date & Time', $body); $body = Html::transformRootRelativeUrlsToAbsolute($body, \Drupal::request()->getSchemeAndHttpHost()); @@ -581,7 +581,7 @@ function officeHours($ids, $utmCampaign = NULL) { if ($body == NULL) { $body = $entity->get('body')->view('list'); $body = $body[0] != NULL ? $body[0] : ''; - $body = \Drupal::service('renderer')->renderPlain($body); + $body = \Drupal::service('renderer')->renderInIsolation($body); } $n = 0; @@ -662,7 +662,7 @@ function newsRangeView($fromDate, $toDate, $utmCampaign) { // Gets format Apr 03, 2023; want 4/3/2023. $pubDate = $node->field_published_date[0]->view('alt_teaser'); - $pubDateDisp = \Drupal::service('renderer')->renderPlain($pubDate); + $pubDateDisp = \Drupal::service('renderer')->renderInIsolation($pubDate); $pubDate = date_create_from_format('M d, Y', $pubDateDisp); $pubDateDisp = $pubDate->format('n/j/Y'); @@ -675,7 +675,7 @@ function newsRangeView($fromDate, $toDate, $utmCampaign) { // will have different spacing in the digest. Or do something with css) if ($node->body[0] != NULL) { $body = $node->body[0]->view('teaser'); - $bodyDisp = \Drupal::service('renderer')->renderPlain($body); + $bodyDisp = \Drupal::service('renderer')->renderInIsolation($body); } else { $bodyDisp = '

    '; @@ -776,10 +776,10 @@ function eventsRangeView($fromDate, $toDate, $type, $type_title, $utmCampaign) . ' - ' . $endDisplay . " " . $tz; $body = empty($enode->description[0]) ? '' : $enode->description[0]->view('rollup_list'); - $bodyDisp = \Drupal::service('renderer')->renderPlain($body); + $bodyDisp = \Drupal::service('renderer')->renderInIsolation($body); // $location = empty($enode->location[0]) ? '' : $enode->location[0]->view('rollup_list'); - // $locationDisp = \Drupal::service('renderer')->renderPlain($location); + // $locationDisp = \Drupal::service('renderer')->renderInIsolation($location); if ($eCount > 1) { $listDisplay = $listDisplay; } diff --git a/modules/ticketing/src/Plugin/WebformHandler/AccountSupportHandler.php b/modules/ticketing/src/Plugin/WebformHandler/AccountSupportHandler.php index dc9b8d0d..cae71f16 100644 --- a/modules/ticketing/src/Plugin/WebformHandler/AccountSupportHandler.php +++ b/modules/ticketing/src/Plugin/WebformHandler/AccountSupportHandler.php @@ -69,7 +69,8 @@ public function postSave(WebformSubmissionInterface $webformSubmission, $update public function getXMailMessageBody($data) { $ticketing_module_path = \Drupal::service('extension.list.module')->getPath('ticketing'); - return twig_render_template( + $twig = \Drupal::service('twig'); + return $twig->render( $ticketing_module_path . '/templates/account-support-mail.html.twig', [ 'theme_hook_original' => 'not-applicable', diff --git a/modules/ticketing/src/Plugin/WebformHandler/RequestOrgsListAddHandler.php b/modules/ticketing/src/Plugin/WebformHandler/RequestOrgsListAddHandler.php index f7f1687c..37dda610 100644 --- a/modules/ticketing/src/Plugin/WebformHandler/RequestOrgsListAddHandler.php +++ b/modules/ticketing/src/Plugin/WebformHandler/RequestOrgsListAddHandler.php @@ -72,7 +72,8 @@ public function postSave(WebformSubmissionInterface $webformSubmission, $update */ public function getMailMessageBody($data) { $ticketing_module_path = \Drupal::service('extension.list.module')->getPath('ticketing'); - return twig_render_template( + $twig = \Drupal::service('twig'); + return $twig->render( $ticketing_module_path . '/templates/request-orgs-list-add-mail.html.twig', [ 'theme_hook_original' => 'not-applicable', diff --git a/modules/ticketing/src/Plugin/WebformHandler/TicketingSendEmailHandler.php b/modules/ticketing/src/Plugin/WebformHandler/TicketingSendEmailHandler.php index f10c05f3..7b1ac759 100644 --- a/modules/ticketing/src/Plugin/WebformHandler/TicketingSendEmailHandler.php +++ b/modules/ticketing/src/Plugin/WebformHandler/TicketingSendEmailHandler.php @@ -195,7 +195,8 @@ public function postSave(WebformSubmissionInterface $webformSubmission, $update public function getXMailMessageBody($description, $tags, $suggested_tag, $from_email) { $ticketing_module_path = \Drupal::service('extension.list.module')->getPath('ticketing'); - return twig_render_template( + $twig = \Drupal::service('twig'); + return $twig->render( $ticketing_module_path . '/templates/ticketing-mail.html.twig', [ 'theme_hook_original' => 'not-applicable', diff --git a/modules/user_profiles/src/Commands/UserProfilesCommands.php b/modules/user_profiles/src/Commands/UserProfilesCommands.php index 6358f837..760564ba 100644 --- a/modules/user_profiles/src/Commands/UserProfilesCommands.php +++ b/modules/user_profiles/src/Commands/UserProfilesCommands.php @@ -97,7 +97,13 @@ private function mergeNodes(User $user_from, User $user_to) { $this->output()->writeln(" " . $node->getTitle()); } - node_mass_update($nodes, ['uid' => $user_to->id()], NULL, TRUE); + foreach ($nodes as $nid) { + $node = Node::load($nid); + if ($node) { + $node->set('uid', $user_to->id()); + $node->save(); + } + } } /** diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 00000000..a9cfd91a --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,435 @@ +parameters: + ignoreErrors: + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 13 + path: modules/access_affinitygroup/src/Commands/AffinityGroupCommands.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 3 + path: modules/access_affinitygroup/src/Controller/SimpleListController.php + + - + message: "#^Cannot call abstract method Drupal\\\\Core\\\\Form\\\\FormInterface\\:\\:submitForm\\(\\)\\.$#" + count: 1 + path: modules/access_affinitygroup/src/Form/ConstantContact.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 19 + path: modules/access_affinitygroup/src/Form/ConstantContact.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 35 + path: modules/access_affinitygroup/src/Plugin/AllocationsUsersImport.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 7 + path: modules/access_affinitygroup/src/Plugin/Block/AffinityBottomLeft.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 3 + path: modules/access_affinitygroup/src/Plugin/Block/AffinityContactGroup.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 3 + path: modules/access_affinitygroup/src/Plugin/Block/AffinityCoordinatorDocumentation.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 12 + path: modules/access_affinitygroup/src/Plugin/Block/ResourcesForAffinityGroup.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 6 + path: modules/access_affinitygroup/src/Plugin/Block/SimpleListMember.php + + - + message: "#^Undefined variable\\: \\$set_email$#" + count: 2 + path: modules/access_affinitygroup/src/Plugin/ConstantContactApi.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 28 + path: modules/access_affinitygroup/src/Plugin/ConstantContactApi.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: modules/access_affinitygroup/src/Plugin/EmailWrapper.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 9 + path: modules/access_affinitygroup/src/Plugin/SimpleListsApi.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: modules/access_affinitygroup/src/Plugin/views/access/ViewsCustomAccess.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 10 + path: modules/access_badges/src/Plugin/BadgeTools.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 19 + path: modules/access_cilink/src/Controller/CiLinkController.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 4 + path: modules/access_cilink/src/EventSubscriber/FlagSubscriber.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 9 + path: modules/access_events/src/Controller/EventWaitlist.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 7 + path: modules/access_events/src/Plugin/Block/EventInstanceSidebar.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 3 + path: modules/access_events/src/Plugin/XsedeApi.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: modules/access_llm/src/AiReferenceGenerator.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 11 + path: modules/access_match_engagement/src/Controller/MatchController.php + + - + message: "#^Unsafe usage of new static\\(\\)\\.$#" + count: 1 + path: modules/access_match_engagement/src/Plugin/Block/MatchNodeBlock.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 2 + path: modules/access_match_engagement/src/Plugin/Block/MatchNodeBlock.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 2 + path: modules/access_misc/src/AccessRegistrantAccessControlHandler.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: modules/access_misc/src/Controller/LoginController.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 14 + path: modules/access_misc/src/EventSubscriber/Subscriber.php + + - + message: """ + #^Fetching deprecated class constant EXISTS_REPLACE of interface Drupal\\\\Core\\\\File\\\\FileSystemInterface\\: + in drupal\\:10\\.3\\.0 and is removed from drupal\\:12\\.0\\.0\\. Use + \\\\Drupal\\\\Core\\\\File\\\\FileExists\\:\\:Replace instead\\.$# + """ + count: 1 + path: modules/access_misc/src/Form/FilterPeopleByTags.php + + - + message: "#^Method Drupal\\\\access_misc\\\\Form\\\\FilterPeopleByTags\\:\\:createTable\\(\\) invoked with 6 parameters, 7 required\\.$#" + count: 1 + path: modules/access_misc/src/Form/FilterPeopleByTags.php + + - + message: "#^Undefined variable\\: \\$fourth_tags$#" + count: 1 + path: modules/access_misc/src/Form/FilterPeopleByTags.php + + - + message: "#^Undefined variable\\: \\$third_tags$#" + count: 1 + path: modules/access_misc/src/Form/FilterPeopleByTags.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: modules/access_misc/src/Form/FilterPeopleByTags.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 2 + path: modules/access_misc/src/Plugin/Block/AccessCiUserLogin.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: modules/access_misc/src/Plugin/Block/CreateSecurityTicket.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: modules/access_misc/src/Plugin/Block/CreateTicket.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 3 + path: modules/access_misc/src/Plugin/JiraLink.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 2 + path: modules/access_misc/src/Plugin/Util/RolesLabelLookup.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: modules/access_misc/src/Plugin/Util/SiteTools.php + + - + message: "#^Deprecated in PHP 8\\.4\\: Parameter \\#1 \\$datasource \\(Drupal\\\\search_api\\\\Datasource\\\\DatasourceInterface\\) is implicitly nullable via default value null\\.$#" + count: 1 + path: modules/access_misc/src/Plugin/search_api/processor/EventAffiliation.php + + - + message: "#^Deprecated in PHP 8\\.4\\: Parameter \\#1 \\$datasource \\(Drupal\\\\search_api\\\\Datasource\\\\DatasourceInterface\\) is implicitly nullable via default value null\\.$#" + count: 1 + path: modules/access_misc/src/Plugin/search_api/processor/EventNoShow.php + + - + message: "#^Deprecated in PHP 8\\.4\\: Parameter \\#1 \\$datasource \\(Drupal\\\\search_api\\\\Datasource\\\\DatasourceInterface\\) is implicitly nullable via default value null\\.$#" + count: 1 + path: modules/access_misc/src/Plugin/search_api/processor/EventSkillLevel.php + + - + message: "#^Deprecated in PHP 8\\.4\\: Parameter \\#1 \\$datasource \\(Drupal\\\\search_api\\\\Datasource\\\\DatasourceInterface\\) is implicitly nullable via default value null\\.$#" + count: 1 + path: modules/access_misc/src/Plugin/search_api/processor/EventTags.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: modules/access_misc/src/Plugin/search_api/processor/EventTags.php + + - + message: "#^Deprecated in PHP 8\\.4\\: Parameter \\#1 \\$datasource \\(Drupal\\\\search_api\\\\Datasource\\\\DatasourceInterface\\) is implicitly nullable via default value null\\.$#" + count: 1 + path: modules/access_misc/src/Plugin/search_api/processor/EventTitle.php + + - + message: "#^Deprecated in PHP 8\\.4\\: Parameter \\#1 \\$datasource \\(Drupal\\\\search_api\\\\Datasource\\\\DatasourceInterface\\) is implicitly nullable via default value null\\.$#" + count: 1 + path: modules/access_misc/src/Plugin/search_api/processor/EventType.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 2 + path: modules/access_misc/src/Plugin/views/access/ViewsRegistrationCustomAccess.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: modules/access_misc/src/Plugin/views/access/ViewsUserRegistrationCustomAccess.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 26 + path: modules/access_misc/src/Services/ImportAccessOrgs.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: modules/access_misc/src/Services/SymfonyMail.php + + - + message: "#^Unsafe usage of new static\\(\\)\\.$#" + count: 1 + path: modules/ccmnet/src/Plugin/Block/MentorshipNodeBlock.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 7 + path: modules/ccmnet/src/Plugin/Block/MentorshipNodeBlock.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 4 + path: modules/ccmnet/src/Plugin/Block/MentorshipPersonBlock.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: modules/ccmnet/src/Plugin/Block/UserRegisterRedirectBlock.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 5 + path: modules/ccmnet/src/Plugin/Util/MentorshipLookup.php + + - + message: "#^Deprecated in PHP 8\\.4\\: Parameter \\#1 \\$datasource \\(Drupal\\\\search_api\\\\Datasource\\\\DatasourceInterface\\) is implicitly nullable via default value null\\.$#" + count: 1 + path: modules/ccmnet/src/Plugin/search_api/processor/MenteeName.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: modules/ccmnet/src/Plugin/search_api/processor/MenteeName.php + + - + message: "#^Method Drupal\\\\cssn\\\\Controller\\\\CommunityPersonaController\\:\\:titleCallback\\(\\) should return string but return statement is missing\\.$#" + count: 1 + path: modules/cssn/src/Controller/CommunityPersonaController.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 12 + path: modules/cssn/src/Controller/CommunityPersonaController.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 3 + path: modules/cssn/src/Plugin/Block/CssnJoinForm.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 7 + path: modules/cssn/src/Plugin/Block/PersonaBlock.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 2 + path: modules/cssn/src/Plugin/Util/CssnSubmissionsSort.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 4 + path: modules/cssn/src/Plugin/Util/MatchLookup.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 2 + path: modules/cssn/src/Plugin/Util/ProjectLookup.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 2 + path: modules/cssn/src/Plugin/Util/RoleProgramSorter.php + + - + message: "#^Deprecated in PHP 8\\.4\\: Parameter \\#1 \\$datasource \\(Drupal\\\\search_api\\\\Datasource\\\\DatasourceInterface\\) is implicitly nullable via default value null\\.$#" + count: 1 + path: modules/cssn/src/Plugin/search_api/processor/UserBadges.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: modules/cssn/src/Plugin/search_api/processor/UserBadges.php + + - + message: "#^Deprecated in PHP 8\\.4\\: Parameter \\#1 \\$datasource \\(Drupal\\\\search_api\\\\Datasource\\\\DatasourceInterface\\) is implicitly nullable via default value null\\.$#" + count: 1 + path: modules/cssn/src/Plugin/search_api/processor/UserInterests.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: modules/cssn/src/Plugin/search_api/processor/UserInterests.php + + - + message: "#^Deprecated in PHP 8\\.4\\: Parameter \\#1 \\$datasource \\(Drupal\\\\search_api\\\\Datasource\\\\DatasourceInterface\\) is implicitly nullable via default value null\\.$#" + count: 1 + path: modules/cssn/src/Plugin/search_api/processor/UserSkills.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: modules/cssn/src/Plugin/search_api/processor/UserSkills.php + + - + message: "#^Deprecated in PHP 8\\.4\\: Parameter \\#1 \\$datasource \\(Drupal\\\\search_api\\\\Datasource\\\\DatasourceInterface\\) is implicitly nullable via default value null\\.$#" + count: 1 + path: modules/cssn/src/Plugin/search_api/processor/UserSkillsId.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: modules/cssn/src/Plugin/search_api/processor/UserSkillsId.php + + - + message: "#^Deprecated in PHP 8\\.4\\: Parameter \\#1 \\$datasource \\(Drupal\\\\search_api\\\\Datasource\\\\DatasourceInterface\\) is implicitly nullable via default value null\\.$#" + count: 1 + path: modules/cssn/src/Plugin/search_api/processor/userAffinityGroups.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: modules/cssn/src/Plugin/search_api/processor/userAffinityGroups.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: modules/ticketing/src/Controller/TicketingController.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 3 + path: modules/ticketing/src/Plugin/Block/TicketingBlock.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 7 + path: modules/ticketing/src/Plugin/WebformHandler/AccountSupportHandler.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 7 + path: modules/ticketing/src/Plugin/WebformHandler/RequestOrgsListAddHandler.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 14 + path: modules/ticketing/src/Plugin/WebformHandler/TicketingSendEmailHandler.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 5 + path: modules/user_profiles/src/Commands/UserProfilesCommands.php + + - + message: "#^Instantiated class Drupal\\\\access_misc\\\\Plugin\\\\Util\\\\FindAccessOrg not found\\.$#" + count: 1 + path: modules/user_profiles/user_profiles.module + + - + message: "#^Undefined variable\\: \\$aUser$#" + count: 1 + path: modules/user_profiles/user_profiles.module + + - + message: "#^Result of function var_dump \\(void\\) is used\\.$#" + count: 1 + path: scripts/reportNewUsersPerMonth.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: src/Commands/AccessCommands.php + + - + message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#" + count: 1 + path: src/Controller/JsonApiAccessController.php diff --git a/phpstan-simple.neon b/phpstan-simple.neon new file mode 100644 index 00000000..4b2eab03 --- /dev/null +++ b/phpstan-simple.neon @@ -0,0 +1,11 @@ +parameters: + level: 0 + paths: + - . + excludePaths: + - tests/* + - */tests/* + - vendor/* + ignoreErrors: + - identifier: missingType.iterableValue + - identifier: missingType.generics \ No newline at end of file From afdf9c6ca5a33526af412bf26bacd229530d020e Mon Sep 17 00:00:00 2001 From: Andrew Pasquale Date: Wed, 20 Aug 2025 11:14:14 -0400 Subject: [PATCH 05/11] Update modules/ticketing/src/Plugin/WebformHandler/TicketingSendEmailHandler.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../src/Plugin/WebformHandler/TicketingSendEmailHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticketing/src/Plugin/WebformHandler/TicketingSendEmailHandler.php b/modules/ticketing/src/Plugin/WebformHandler/TicketingSendEmailHandler.php index 7b1ac759..2d5e4885 100644 --- a/modules/ticketing/src/Plugin/WebformHandler/TicketingSendEmailHandler.php +++ b/modules/ticketing/src/Plugin/WebformHandler/TicketingSendEmailHandler.php @@ -196,7 +196,7 @@ public function postSave(WebformSubmissionInterface $webformSubmission, $update public function getXMailMessageBody($description, $tags, $suggested_tag, $from_email) { $ticketing_module_path = \Drupal::service('extension.list.module')->getPath('ticketing'); $twig = \Drupal::service('twig'); - return $twig->render( + return $this->twig->render( $ticketing_module_path . '/templates/ticketing-mail.html.twig', [ 'theme_hook_original' => 'not-applicable', From df6ca507fc3d4e3e78bc1f26b5a1b44b5152a380 Mon Sep 17 00:00:00 2001 From: Andrew Pasquale Date: Wed, 20 Aug 2025 11:14:24 -0400 Subject: [PATCH 06/11] Update modules/ticketing/src/Plugin/WebformHandler/RequestOrgsListAddHandler.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../src/Plugin/WebformHandler/RequestOrgsListAddHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticketing/src/Plugin/WebformHandler/RequestOrgsListAddHandler.php b/modules/ticketing/src/Plugin/WebformHandler/RequestOrgsListAddHandler.php index 37dda610..20ba29d8 100644 --- a/modules/ticketing/src/Plugin/WebformHandler/RequestOrgsListAddHandler.php +++ b/modules/ticketing/src/Plugin/WebformHandler/RequestOrgsListAddHandler.php @@ -73,7 +73,7 @@ public function postSave(WebformSubmissionInterface $webformSubmission, $update public function getMailMessageBody($data) { $ticketing_module_path = \Drupal::service('extension.list.module')->getPath('ticketing'); $twig = \Drupal::service('twig'); - return $twig->render( + return $this->twig->render( $ticketing_module_path . '/templates/request-orgs-list-add-mail.html.twig', [ 'theme_hook_original' => 'not-applicable', From 25556252c24aa6117636ca561665f14c4939a21d Mon Sep 17 00:00:00 2001 From: Andrew Pasquale Date: Wed, 20 Aug 2025 11:14:34 -0400 Subject: [PATCH 07/11] Update modules/ticketing/src/Plugin/WebformHandler/AccountSupportHandler.php Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../src/Plugin/WebformHandler/AccountSupportHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/ticketing/src/Plugin/WebformHandler/AccountSupportHandler.php b/modules/ticketing/src/Plugin/WebformHandler/AccountSupportHandler.php index cae71f16..89cd4dd0 100644 --- a/modules/ticketing/src/Plugin/WebformHandler/AccountSupportHandler.php +++ b/modules/ticketing/src/Plugin/WebformHandler/AccountSupportHandler.php @@ -70,7 +70,7 @@ public function postSave(WebformSubmissionInterface $webformSubmission, $update public function getXMailMessageBody($data) { $ticketing_module_path = \Drupal::service('extension.list.module')->getPath('ticketing'); $twig = \Drupal::service('twig'); - return $twig->render( + return $this->twig->render( $ticketing_module_path . '/templates/account-support-mail.html.twig', [ 'theme_hook_original' => 'not-applicable', From 3e3d37ed0ac8e8507bef236cfb1337faec1ad1f1 Mon Sep 17 00:00:00 2001 From: Andrew Pasquale Date: Wed, 20 Aug 2025 11:21:45 -0400 Subject: [PATCH 08/11] Fix incorrect twig service references and remove redundant phpstan-simple.neon --- .../Plugin/WebformHandler/AccountSupportHandler.php | 2 +- .../WebformHandler/RequestOrgsListAddHandler.php | 2 +- .../WebformHandler/TicketingSendEmailHandler.php | 2 +- phpstan-simple.neon | 11 ----------- 4 files changed, 3 insertions(+), 14 deletions(-) delete mode 100644 phpstan-simple.neon diff --git a/modules/ticketing/src/Plugin/WebformHandler/AccountSupportHandler.php b/modules/ticketing/src/Plugin/WebformHandler/AccountSupportHandler.php index 89cd4dd0..cae71f16 100644 --- a/modules/ticketing/src/Plugin/WebformHandler/AccountSupportHandler.php +++ b/modules/ticketing/src/Plugin/WebformHandler/AccountSupportHandler.php @@ -70,7 +70,7 @@ public function postSave(WebformSubmissionInterface $webformSubmission, $update public function getXMailMessageBody($data) { $ticketing_module_path = \Drupal::service('extension.list.module')->getPath('ticketing'); $twig = \Drupal::service('twig'); - return $this->twig->render( + return $twig->render( $ticketing_module_path . '/templates/account-support-mail.html.twig', [ 'theme_hook_original' => 'not-applicable', diff --git a/modules/ticketing/src/Plugin/WebformHandler/RequestOrgsListAddHandler.php b/modules/ticketing/src/Plugin/WebformHandler/RequestOrgsListAddHandler.php index 20ba29d8..37dda610 100644 --- a/modules/ticketing/src/Plugin/WebformHandler/RequestOrgsListAddHandler.php +++ b/modules/ticketing/src/Plugin/WebformHandler/RequestOrgsListAddHandler.php @@ -73,7 +73,7 @@ public function postSave(WebformSubmissionInterface $webformSubmission, $update public function getMailMessageBody($data) { $ticketing_module_path = \Drupal::service('extension.list.module')->getPath('ticketing'); $twig = \Drupal::service('twig'); - return $this->twig->render( + return $twig->render( $ticketing_module_path . '/templates/request-orgs-list-add-mail.html.twig', [ 'theme_hook_original' => 'not-applicable', diff --git a/modules/ticketing/src/Plugin/WebformHandler/TicketingSendEmailHandler.php b/modules/ticketing/src/Plugin/WebformHandler/TicketingSendEmailHandler.php index 2d5e4885..7b1ac759 100644 --- a/modules/ticketing/src/Plugin/WebformHandler/TicketingSendEmailHandler.php +++ b/modules/ticketing/src/Plugin/WebformHandler/TicketingSendEmailHandler.php @@ -196,7 +196,7 @@ public function postSave(WebformSubmissionInterface $webformSubmission, $update public function getXMailMessageBody($description, $tags, $suggested_tag, $from_email) { $ticketing_module_path = \Drupal::service('extension.list.module')->getPath('ticketing'); $twig = \Drupal::service('twig'); - return $this->twig->render( + return $twig->render( $ticketing_module_path . '/templates/ticketing-mail.html.twig', [ 'theme_hook_original' => 'not-applicable', diff --git a/phpstan-simple.neon b/phpstan-simple.neon deleted file mode 100644 index 4b2eab03..00000000 --- a/phpstan-simple.neon +++ /dev/null @@ -1,11 +0,0 @@ -parameters: - level: 0 - paths: - - . - excludePaths: - - tests/* - - */tests/* - - vendor/* - ignoreErrors: - - identifier: missingType.iterableValue - - identifier: missingType.generics \ No newline at end of file From 55b42aabdc28834c453433c51efd52ff22706549 Mon Sep 17 00:00:00 2001 From: Andrew Pasquale Date: Thu, 21 Aug 2025 18:39:41 -0400 Subject: [PATCH 09/11] Test commit --- access.module | 1 + 1 file changed, 1 insertion(+) diff --git a/access.module b/access.module index 33127349..2a455170 100644 --- a/access.module +++ b/access.module @@ -12,6 +12,7 @@ use Drupal\Core\Menu\MenuTreeParameters; */ function access_page_attachments(array &$attachments) { $token = \Drupal::token(); + $test = $new_var; $domain_name = Html::getClass($token->replace(t('[domain:name]'))); if ($domain_name == "access-support") { From 56bc2e99278874a4b8758e16044c5eb195c7db81 Mon Sep 17 00:00:00 2001 From: Andrew Pasquale Date: Thu, 21 Aug 2025 18:47:21 -0400 Subject: [PATCH 10/11] Revert "Test commit" This reverts commit 55b42aabdc28834c453433c51efd52ff22706549. --- access.module | 1 - 1 file changed, 1 deletion(-) diff --git a/access.module b/access.module index 2a455170..33127349 100644 --- a/access.module +++ b/access.module @@ -12,7 +12,6 @@ use Drupal\Core\Menu\MenuTreeParameters; */ function access_page_attachments(array &$attachments) { $token = \Drupal::token(); - $test = $new_var; $domain_name = Html::getClass($token->replace(t('[domain:name]'))); if ($domain_name == "access-support") { From 8d7997a82078f168dbca89af916e5cab1de157dc Mon Sep 17 00:00:00 2001 From: Andrew Pasquale Date: Thu, 21 Aug 2025 18:55:40 -0400 Subject: [PATCH 11/11] GitHub action for precommit hooks --- .github/workflows/pre-commit.yml | 15 +++ README.md | 179 +++++++++++++++++++++++++++++++ 2 files changed, 194 insertions(+) create mode 100644 .github/workflows/pre-commit.yml create mode 100644 README.md diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml new file mode 100644 index 00000000..ecedcec0 --- /dev/null +++ b/.github/workflows/pre-commit.yml @@ -0,0 +1,15 @@ +name: Pre-commit + +on: + push: + pull_request: + +jobs: + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v4 + with: + python-version: '3.x' + - uses: pre-commit/action@v3.0.0 \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 00000000..bf2323a5 --- /dev/null +++ b/README.md @@ -0,0 +1,179 @@ +# ACCESS Module + +A collection of Drupal modules for ACCESS Match and related cyberinfrastructure platforms. + +## Overview + +The ACCESS module is a custom Drupal module suite that provides functionality for the ACCESS (Advanced Cyberinfrastructure Coordination Ecosystem: Services & Support) ecosystem. This module contains several sub-modules that handle different aspects of the ACCESS platform, including affinity groups, CI links, mentorship, and various specialized features. + +## Development Setup + +### Prerequisites +- PHP 8.1+ +- Drupal 9 or 10 +- Composer + +### Installation +1. Clone this repository into your Drupal installation's `web/modules/custom/access` directory +2. Install dependencies: + ```bash + composer install + ``` + +3. Install pre-commit hooks for code quality: + ```bash + pre-commit install + ``` + This ensures PHPStan analysis runs automatically before each commit. + +### Code Quality +This module uses PHPStan for static analysis to catch issues before they reach production. + +#### Linting Commands +```bash +# Run PHPStan analysis +composer lint + +# Generate new baseline (when adding new code with acceptable issues) +composer lint:baseline +``` + +#### Pre-commit Hooks +- Automatically runs PHPStan on PHP files before commits +- Configuration: `.pre-commit-config.yaml` +- PHPStan config: `phpstan.neon` +- Baseline: `phpstan-baseline.neon` + +## Sub-modules + +### Core Modules + +#### access_affinitygroup +**Purpose**: Custom functionality for Affinity Groups +- Manages affinity group memberships and interactions +- Provides blocks for affinity group content +- Handles email notifications and group communications +- Integrates with ConstantContact API + +#### access_badges +**Purpose**: Badge system management +- Handles user achievement badges +- Provides badge display and management tools + +#### access_cilink +**Purpose**: CI Link customizations +- Manages cyberinfrastructure resource links +- Handles resource flagging and voting +- Provides resource view enhancements + +#### access_events +**Purpose**: Event management functionality +- Event waitlist management +- Event instance sidebar blocks +- Integration with XSEDE API for event data + +#### access_llm +**Purpose**: AI/LLM integration +- AI reference generation capabilities +- Integrates with OpenAI API + +#### access_match_engagement +**Purpose**: Match engagement tracking +- Tracks user engagement with matches +- Provides engagement analytics and reporting + +#### access_misc +**Purpose**: Miscellaneous ACCESS utilities +- User login customizations +- General site tools and utilities +- Security ticket creation +- People directory functionality +- Custom tags and search enhancements + +#### access_news +**Purpose**: News and announcements +- News and events display blocks +- Request news submission functionality + +#### access_outages +**Purpose**: System outage notifications +- Displays current system outages +- Affinity group-specific outage information + +#### access_shortcodes +**Purpose**: Content shortcode system +- Accordion shortcodes +- CTA (Call-to-Action) blocks +- Icon blocks +- Square content blocks + +### Platform-Specific Modules + +#### ccmnet +**Purpose**: CCMnet (Campus Champions Mentorship Network) functionality +- Mentorship program management +- Mentor-mentee matching and tracking +- Mentorship engagement metrics +- User registration redirects + +#### cssn +**Purpose**: CSSN (Community for Science Software and Network) features +- Community persona management +- User directory with skills/interests +- Project and match lookup functionality +- Join form and community features + +#### ondemand +**Purpose**: OnDemand platform integration +- Basic OnDemand platform support + +#### ticketing +**Purpose**: Support ticket system +- Account support ticket creation +- Organization list management +- Email notifications for tickets +- Webform integration + +#### user_profiles +**Purpose**: Enhanced user profile functionality +- Extended user profile management +- Organization toggle features +- User profile commands and utilities + +## Dependencies + +### PHP Packages +- `openai-php/client`: OpenAI API integration +- `gioni06/gpt3-tokenizer`: GPT tokenization support + +### Development Dependencies +- `phpstan/phpstan`: Static analysis +- `mglaman/phpstan-drupal`: Drupal-specific PHPStan rules + +## Support + +- **Issues**: [GitHub Issues](https://github.com/necyberteam/access/issues) +- **Source**: [GitHub Repository](https://github.com/necyberteam/access) + +## Contributing + +1. Fork the repository +2. Create a feature branch +3. Install pre-commit hooks: `pre-commit install` +4. Make your changes +5. Ensure all code quality checks pass +6. Submit a pull request + +## License + +GPL-2.0+ + +## Authors + +- Miles France (@protitude) +- Andrew Pasquale +- FloQuinn (@FloQuinn) +- Hannah L Cameron (@laheara143) +- Jasper Lieber +- Lissie F (@lissief) +- Shawn Rice \ No newline at end of file