πŸ‡§πŸ‡ͺBelgium @Robin.Houtevelts

Account created on 7 October 2016, about 8 years ago
  • Backend developer at WieniΒ 
#

Merge Requests

Recent comments

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

I was having the same problem.
As #5 mentioned, I had a bad vendor/phpstan/extension-installer/src/GeneratedConfig.php.

In my composer.json I had to enable the phpstan/extension-installer plugin in the allow-plugins section.

My GeneratedConfig.php file was empty.


namespace PHPStan\ExtensionInstaller;

/**
 * This is a stub class: it is in place only for scenarios where Composer
 * is run with a `--no-scripts` flag, in which scenarios this stub class
 * is not being replaced.
 *
 * If you are reading this docBlock inside your `vendor/` dir, then this means
 * that phpstan/extension-installer didn't correctly install.
 *
 * @internal
 */
final class GeneratedConfig
{

	public const EXTENSIONS = [];

	public const NOT_INSTALLED = [];

	public const PHPSTAN_VERSION_CONSTRAINT = null;

	private function __construct()
	{
	}

}

After enabling the composer plugin everything works as expected.

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

robin.houtevelts β†’ changed the visibility of the branch 3.x to hidden.

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

robin.houtevelts β†’ made their first commit to this issue’s fork.

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

Thanks @DieterHolvoet!
Test pipeline is still being run against Drupal 10, so if you tested with Drupal 11 I think it's safe to commit this πŸš€

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

I think we just need to create a new 3.0.0 release.

Dieter already added Drush 12 (and Drupal 10) support in https://www.drupal.org/project/entity_bundle_scaffold/issues/3367659 πŸ“Œ Add support for Drush 12 Fixed

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

I don't immediately see any incompatible changes when I check v6.4.8...7.1 so it makes sense to mark this compatible with ^7.0 too.

It's a bit late here right now, I'll take a closer look after a good night of sleep.

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

Thanks for reviewing and merging this πŸ™
Are there plans of creating a new release anytime soon?

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

After applying the patch above I was still seeing this error.
In my case I was using drupal/office_hours β†’ which seems to call the ModuleHandler very very early in their .module file.

I fixed it by replacing those two lines with:

require_once __DIR__ . '/office_hours.theme.inc';
require_once __DIR__ . '/office_hours.theme.exceptions.inc';

Leaving it here in case it might help someone else.

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

Works for me. Changing to RTBC.

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

Cool!
I'm actually planned to update one of our projects to 10.2 this week.
That project currently has a module whose HOOK_entity_type_alter appears to run after node_singles too -just like Trash- but *doesn't* extend/wrap this AccessHandler.

So I think I can test this exact use case.
I'll test this once I get to 10.2 somewhere this or next week, and let you know here.

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

Isn't that fixed by the node_singles_module_implements_alter added in this MR?
Then we decorate whatever was final.

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

I see. Thanks for clarifying!

let me know if you do.

No, not without being fonky.
Ideally the AccessHandler would be an actual service we could decorate.
But something like this might make sure we can decorate the previously defined handler too.

But it might be a bit too fonky..

function node_singles_entity_type_alter(array &$entityTypes): void {
  \Drupal::getContainer()->get('state')
    ->set(
        SingleNodeAccessControlHandler::STATE_DECORATED_CLASS_KEY,
        $entityTypes['node']->getHandlerClass('access')
     )

  $entityTypes['node']->setHandlerClass('access', SingleNodeAccessControlHandler::class);
  $entityTypes['node_type']->setFormClass('delete', SingleNodeTypeDeleteConfirm::class);
}

use Drupal\Core\Entity\EntityAccessControlHandlerInterface;
use Drupal\Core\Entity\EntityHandlerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\State\StateInterface;
use Drupal\node\NodeAccessControlHandler;
use Drupal\node\NodeAccessControlHandlerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class SingleNodeAccessControlHandler implements NodeAccessControlHandlerInterface, EntityAccessControlHandlerInterface, EntityHandlerInterface
{

    protected EntityTypeInterface $entityType;
    protected EntityTypeManagerInterface $entityTypeManager;
    protected StateInterface $state;
    protected NodeAccessControlHandlerInterface&EntityAccessControlHandlerInterface $decorated;

    public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type)
    {
        $self = new self();
        $self->entityType = $entity_type;
        $self->entityTypeManager = $container->get('entity_type.manager');
        $self->state = $container->get('state');

        return $self;
    }

    /**
     * {@inheritdoc}
     */
    public function access(EntityInterface $entity, $operation, AccountInterface $account = NULL, $return_as_object = FALSE)
    {
        return $this->decorated()->access($entity, $operation, $account, $return_as_object);
    }

    /**
     * {@inheritdoc}
     */
    public function createAccess($entity_bundle = NULL, AccountInterface $account = NULL, array $context = [], $return_as_object = FALSE)
    {
        return $this->decorated()->createAccess($entity_bundle, $account, $context, $return_as_object);
    }

    /**
     * {@inheritdoc}
     */
    public function resetCache()
    {
        $this->decorated()->resetCache();
    }

    /**
     * {@inheritdoc}
     */
    public function setModuleHandler(ModuleHandlerInterface $module_handler)
    {
        $this->decorated()->setModuleHandler($module_handler);
        return $this;
    }

    /**
     * {@inheritdoc}
     */
    public function fieldAccess($operation, FieldDefinitionInterface $field_definition, AccountInterface $account = NULL, FieldItemListInterface $items = NULL, $return_as_object = FALSE)
    {
        return $this->decorated()->fieldAccess($operation, $field_definition, $account, $items, $return_as_object);
    }

    /**
     * {@inheritdoc}
     */
    public function acquireGrants(NodeInterface $node)
    {
        return $this->decorated()->acquireGrants($node);
    }

    /**
     * {@inheritdoc}
     */
    public function writeDefaultGrant()
    {
        $this->decorated()->writeDefaultGrant();
    }

    /**
     * {@inheritdoc}
     */
    public function deleteGrants()
    {
        $this->decorated()->deleteGrants();
    }

    /**
     * {@inheritdoc}
     */
    public function countGrants()
    {
        return $this->decorated()->countGrants();
    }

    /**
     * {@inheritdoc}
     */
    public function checkAllGrants(AccountInterface $account)
    {
        return $this->decorated()->checkAllGrants($account);
    }

    private function decorated(): NodeAccessControlHandlerInterface&EntityAccessControlHandlerInterface
    {
        if (isset($this->decorated)) {
            return $this->decorated;
        }
        $originalAccessHandlerClass = $this->state->get(self::STATE_DECORATED_CLASS_KEY, NodeAccessControlHandler::class);
        $handler = $this->entityTypeManager->createHandlerInstance($originalAccessHandlerClass, $this->entityType);

        if (!$handler instanceof NodeAccessControlHandlerInterface) {
            throw new \InvalidArgumentException('The decorated access control handler must implement NodeAccessControlHandlerInterface.');
        }
        if (!$handler instanceof EntityAccessControlHandlerInterface) {
            throw new \InvalidArgumentException('The decorated access control handler must implement EntityAccessControlHandlerInterface.');
        }

        return $handler;
    }
}
πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

This might be a good moment to ask this:
Do we really need to define our own AccessHandler?

Should we use access hooks instead so we don't have to do this for each module that also wants to define an AccessHandler?

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

Seems to work! Thanks!
Not sure this is worthy of a changelog entry, so LGTM πŸŽ‰

diff --git a/config/sync/node.type.article.yml b/config/sync/node.type.article.yml
index 0a94094b7..d259d783e 100644
--- a/config/sync/node.type.article.yml
+++ b/config/sync/node.type.article.yml
@@ -7,7 +7,7 @@ dependencies:
     - node_singles
 third_party_settings:
   node_singles:
-    is_single: 0
+    is_single: false
   menu_ui:
     available_menus: {  }
     parent: ''
diff --git a/config/sync/node.type.homepage.yml b/config/sync/node.type.homepage.yml
index dcf01fd47..6aae14164 100644
--- a/config/sync/node.type.homepage.yml
+++ b/config/sync/node.type.homepage.yml
@@ -10,7 +10,7 @@ third_party_settings:
     available_menus: {  }
     parent: ''
   node_singles:
-    is_single: 1
+    is_single: true
 name: Homepage
 type: homepage
 description: 'Homepage (homepage)'
--- a/config/sync/node.type.news_overview.yml
+++ b/config/sync/node.type.news_overview.yml
@@ -10,7 +10,7 @@ third_party_settings:
     available_menus: {  }
     parent: ''
   node_singles:
-    is_single: 1
+    is_single: true
 name: 'News overview'
 type: news_overview
 description: 'News overview (news_overview)'

...
πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

Thanks for the suggestion!
I've implemented it and will create a new release shortly.

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

Changing the title to reflect that we want to be able to filter by the different mapped statuses (mapped/unmapped)

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

This module doesn't aim to do much more than it currently does: registering service definitions the way it is done by the Symfony bundle.
Other modules can provide the higher-level niceties you mention (Views, an overview, ...).
I'm happy to see that drupal/inotify β†’ already takes a stab at this.
(In the future we might be open to adding such things as a submodule.)

For documentation on how to use/configure this module I think the Symfony Mercure Bundle documentation is the best resource.
For setting up a Mercure Hub, refer to the official installation guide.
And of course the getting started guide.

It's a relatively young module and Mercure is being used more in Symfony/Api-Platform projects.
At the moment I'm not aware of other Drupal modules using Mercure so I can't provide a starting point unfortunately.
I'll keep this open for others to promote their work 🀞

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

Thanks for the MR and sorry I haven't reviewed this in time πŸ™
Unfortunately we dropped support for Drupal core <9.5 in πŸ“Œ Remove MercureServiceProvider::registr workaround Fixed .

Please consider upgrading your project.
Happy holidays!

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

I have updated the Readme in πŸ“Œ Add Drupal 10 compatibility Fixed .
Thanks for the suggestion! And sorry it took so long for me to respond πŸ™

Happy holidays!

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

This has been taken into account in πŸ“Œ Add Drupal 10 compatibility Fixed and fixed there.
The minimum core version has been increased to 9.5

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

I can also confirm I'm still having this problem on 10.1.
Applying #177 resolved it for me.

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

This is broken in upcoming Drupal 10.2 https://www.drupal.org/project/drupal/issues/3301573 πŸ“Œ Remove the aggregate stale file threshold and state entry Fixed
They have removed the state property https://git.drupalcode.org/project/drupal/-/commit/405f8b33a7d0643ba39bf...

I'm getting

PHP Fatal error: Uncaught Error: Call to a member function delete() on null in

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

I'll try to get it reviewed this week. Thanks for the reminder!

πŸ‡§πŸ‡ͺBelgium Robin.Houtevelts

I stumbled upon this issue through my RSS feed on the change records.
However it doesn't read like a CR.

I agree that it needs a different text and an example usage.

Production build 0.71.5 2024