From 35a1e2defd0710ecf1a9f5e322fae1dbe3f30feb Mon Sep 17 00:00:00 2001 From: Neil Drumm <drumm@delocalizedham.com> Date: Wed, 11 Jun 2025 13:12:21 -0400 Subject: [PATCH 1/7] =?UTF-8?q?Add=20checking=20for=20view=20unpublished?= =?UTF-8?q?=20=E2=80=A6=20content?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- drupalorg.module | 17 ++++++++ .../views/filter/DrupalOrgNodeStatus.php | 41 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/Plugin/views/filter/DrupalOrgNodeStatus.php diff --git a/drupalorg.module b/drupalorg.module index a432022f8..6abef86ec 100644 --- a/drupalorg.module +++ b/drupalorg.module @@ -588,6 +588,23 @@ function drupalorg_entity_field_access($operation, FieldDefinitionInterface $fie return AccessResult::neutral(); } +/** + * Implements hook_views_data_alter(). + */ +function drupalorg_views_data_alter(array &$data) { + $data['node_field_data']['drupalorg_node_status'] = [ + 'title' => t('Published status or admin user (Drupal.org)'), + 'help' => t('Filters out unpublished content if the current user cannot view it, including “view unpublished … content” access.'), + 'filter' => [ + 'field' => 'status', + 'id' => 'drupalorg_node_status', + 'label' => t('Published status, admin user, or allowed unpublished content.'), + ], + ]; + + $data['node_field_data']['status_extra']['filter']['id'] = 'drupalorg_node_status'; +} + // Workaround for missing dependency error caused from the project module not // being ported. // Impacts node.field_issue_sa_version and node.field_issue_version. diff --git a/src/Plugin/views/filter/DrupalOrgNodeStatus.php b/src/Plugin/views/filter/DrupalOrgNodeStatus.php new file mode 100644 index 000000000..7898ce94c --- /dev/null +++ b/src/Plugin/views/filter/DrupalOrgNodeStatus.php @@ -0,0 +1,41 @@ +<?php + +namespace Drupal\drupalorg\Plugin\views\filter; + +use Drupal; +use Drupal\node\Entity\NodeType; +use Drupal\node\Plugin\views\filter\Status; +use Drupal\views\Attribute\ViewsFilter; + +/** + * Filter by published status. + * + * @ingroup views_filter_handlers + */ +#[ViewsFilter("drupalorg_node_status")] +class DrupalOrgNodeStatus extends Status { + + /** + * {@inheritdoc} + */ + public function query() { + $table = $this->ensureMyTable(); + $snippet = "$table.status = 1 OR ($table.uid = ***CURRENT_USER*** AND ***CURRENT_USER*** <> 0 AND ***VIEW_OWN_UNPUBLISHED_NODES*** = 1) OR ***BYPASS_NODE_ACCESS*** = 1"; + if ($this->moduleHandler->moduleExists('content_moderation')) { + $snippet .= ' OR ***VIEW_ANY_UNPUBLISHED_NODES*** = 1'; + } + + $args[':unpublished_type_access[]'] = []; + foreach (array_keys(NodeType::loadMultiple()) as $node_type_id) { + if (Drupal::currentUser()->hasPermission("view any unpublished $node_type_id content")) { + $args[':unpublished_type_access[]'][] = $node_type_id; + } + } + if (!empty($args[':unpublished_type_access[]'])) { + $snippet .= ' OR ' . $table . '.type IN (:unpublished_type_access[])'; + } + + $this->query->addWhereExpression($this->options['group'], $snippet, $args); + } + +} -- GitLab From 6479350beed1c370b3d287a0ef583f887e5b2aca Mon Sep 17 00:00:00 2001 From: Neil Drumm <drumm@delocalizedham.com> Date: Wed, 11 Jun 2025 13:36:29 -0400 Subject: [PATCH 2/7] Remove unused use --- drupalorg.module | 1 - 1 file changed, 1 deletion(-) diff --git a/drupalorg.module b/drupalorg.module index 6abef86ec..1b39daa90 100644 --- a/drupalorg.module +++ b/drupalorg.module @@ -5,7 +5,6 @@ * Drupal.org Custom Migrations. */ -use Drupal\Component\Utility\Xss; use Drupal\Core\Entity\EntityForm; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FieldItemListInterface; -- GitLab From 277073c8d15236eecdcfcb9a91fef17438853c65 Mon Sep 17 00:00:00 2001 From: Neil Drumm <drumm@delocalizedham.com> Date: Wed, 11 Jun 2025 13:39:44 -0400 Subject: [PATCH 3/7] Remove deleted role --- drupalorg.permissions.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drupalorg.permissions.yml b/drupalorg.permissions.yml index 4f03cbdfd..58ebe5dcc 100644 --- a/drupalorg.permissions.yml +++ b/drupalorg.permissions.yml @@ -229,12 +229,6 @@ manage security releases: # translate content # use panels in place editing # view any unpublished book_listing content -#Permissions of user role: "Packaging whitelist maintainer": -# bypass honeypot protection -# delete terms in 58 -# edit terms in 58 -# pift re-test files -# setup own tfa #Permissions of user role: "security team": # administer multiple emails # administer projects -- GitLab From 0f8e62d3646898cd3fd34d4e9c7f848bdf0991bb Mon Sep 17 00:00:00 2001 From: Neil Drumm <drumm@delocalizedham.com> Date: Wed, 11 Jun 2025 14:07:28 -0400 Subject: [PATCH 4/7] Use dependency injection --- .../views/filter/DrupalOrgNodeStatus.php | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/Plugin/views/filter/DrupalOrgNodeStatus.php b/src/Plugin/views/filter/DrupalOrgNodeStatus.php index 7898ce94c..ebace9958 100644 --- a/src/Plugin/views/filter/DrupalOrgNodeStatus.php +++ b/src/Plugin/views/filter/DrupalOrgNodeStatus.php @@ -1,11 +1,14 @@ <?php +declare(strict_types=1); namespace Drupal\drupalorg\Plugin\views\filter; -use Drupal; +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\Session\AccountInterface; use Drupal\node\Entity\NodeType; use Drupal\node\Plugin\views\filter\Status; use Drupal\views\Attribute\ViewsFilter; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Filter by published status. @@ -13,7 +16,29 @@ use Drupal\views\Attribute\ViewsFilter; * @ingroup views_filter_handlers */ #[ViewsFilter("drupalorg_node_status")] -class DrupalOrgNodeStatus extends Status { +class DrupalOrgNodeStatus extends Status implements ContainerFactoryPluginInterface { + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('current_user'), + ); + } + + /** + * AllowedContentTypes constructor. + * + * @param \Drupal\Core\Session\AccountInterface $currentUser + * The current user. + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition, private readonly AccountInterface $currentUser) { + parent::__construct($configuration, $plugin_id, $plugin_definition); + } /** * {@inheritdoc} @@ -27,7 +52,7 @@ class DrupalOrgNodeStatus extends Status { $args[':unpublished_type_access[]'] = []; foreach (array_keys(NodeType::loadMultiple()) as $node_type_id) { - if (Drupal::currentUser()->hasPermission("view any unpublished $node_type_id content")) { + if ($this->currentUser->hasPermission("view any unpublished $node_type_id content")) { $args[':unpublished_type_access[]'][] = $node_type_id; } } -- GitLab From 676ecd1c88b21e307397b659fa6289a9f568b6ce Mon Sep 17 00:00:00 2001 From: Neil Drumm <drumm@delocalizedham.com> Date: Wed, 11 Jun 2025 14:14:20 -0400 Subject: [PATCH 5/7] Coding standards --- src/Plugin/views/filter/DrupalOrgNodeStatus.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Plugin/views/filter/DrupalOrgNodeStatus.php b/src/Plugin/views/filter/DrupalOrgNodeStatus.php index ebace9958..62611b834 100644 --- a/src/Plugin/views/filter/DrupalOrgNodeStatus.php +++ b/src/Plugin/views/filter/DrupalOrgNodeStatus.php @@ -1,4 +1,5 @@ <?php + declare(strict_types=1); namespace Drupal\drupalorg\Plugin\views\filter; @@ -31,10 +32,7 @@ class DrupalOrgNodeStatus extends Status implements ContainerFactoryPluginInterf } /** - * AllowedContentTypes constructor. - * - * @param \Drupal\Core\Session\AccountInterface $currentUser - * The current user. + * {@inheritdoc} */ public function __construct(array $configuration, $plugin_id, $plugin_definition, private readonly AccountInterface $currentUser) { parent::__construct($configuration, $plugin_id, $plugin_definition); -- GitLab From 437a2818fc177a549a4f6306f2e7891fea12bc89 Mon Sep 17 00:00:00 2001 From: Neil Drumm <drumm@delocalizedham.com> Date: Wed, 11 Jun 2025 14:32:49 -0400 Subject: [PATCH 6/7] Formatting --- src/Plugin/views/filter/DrupalOrgNodeStatus.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Plugin/views/filter/DrupalOrgNodeStatus.php b/src/Plugin/views/filter/DrupalOrgNodeStatus.php index 62611b834..9ea13d975 100644 --- a/src/Plugin/views/filter/DrupalOrgNodeStatus.php +++ b/src/Plugin/views/filter/DrupalOrgNodeStatus.php @@ -48,7 +48,9 @@ class DrupalOrgNodeStatus extends Status implements ContainerFactoryPluginInterf $snippet .= ' OR ***VIEW_ANY_UNPUBLISHED_NODES*** = 1'; } - $args[':unpublished_type_access[]'] = []; + $args = [ + ':unpublished_type_access[]' => [], + ]; foreach (array_keys(NodeType::loadMultiple()) as $node_type_id) { if ($this->currentUser->hasPermission("view any unpublished $node_type_id content")) { $args[':unpublished_type_access[]'][] = $node_type_id; -- GitLab From ca87cc521d35db6d93c4d1a0bdaa0320917d89d4 Mon Sep 17 00:00:00 2001 From: Neil Drumm <drumm@delocalizedham.com> Date: Wed, 11 Jun 2025 16:17:30 -0400 Subject: [PATCH 7/7] Do not silently override core-provided filter --- drupalorg.module | 2 -- 1 file changed, 2 deletions(-) diff --git a/drupalorg.module b/drupalorg.module index 1b39daa90..c8b0e8c8e 100644 --- a/drupalorg.module +++ b/drupalorg.module @@ -600,8 +600,6 @@ function drupalorg_views_data_alter(array &$data) { 'label' => t('Published status, admin user, or allowed unpublished content.'), ], ]; - - $data['node_field_data']['status_extra']['filter']['id'] = 'drupalorg_node_status'; } // Workaround for missing dependency error caused from the project module not -- GitLab