Skip to main content
Edit: Corrected the exception that is thrown.
Source Link

I created a logger service that uses a config entity for configuration: https://drupal.org/project/dblog_persistent

Unfortunately, it appears that this module is not installable on a new site, because Drupal attempts to instantiate the logger service before actually installing the config entity type it depends on - the result is an InvalidPluginDefinitionExceptiona PluginNotFoundException.

There has to be some way to prevent services from being instantiated until the module is installed, or not?

This is the class and constructor definition:

<?php

namespace Drupal\dblog_persistent\Logger;

use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Config\Entity\ConfigEntityStorage;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Logger\LogMessageParserInterface;
use Drupal\dblog\Logger\DbLog;
use Drupal\dblog_persistent\DbLogPersistentStorageInterface;

/**
 * Class DbLogPersistent
 *
 * @package Drupal\dblog_persistent\Logger
 */
class DbLogPersistent extends DbLog {

  /**
   * @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
   */
  protected $channelStorage;

  /**
   * @var \Drupal\dblog_persistent\DbLogPersistentStorageInterface
   */
  private $storage;

  /**
   * @var \Drupal\dblog_persistent\Entity\ChannelInterface[]
   */
  private $channels;

  public function __construct(Connection $connection,
                              LogMessageParserInterface $parser,
                              EntityTypeManagerInterface $manager,
                              DbLogPersistentStorageInterface $storage) {
    parent::__construct($connection, $parser);
    // The following causes an error on installation:
    $this->channelStorage = $manager->getStorage('dblog_persistent_channel');
    $this->storage = $storage;
  }

And the service definition:

services:
  dblog_persistent.storage:
    class: Drupal\dblog_persistent\DbLogPersistentStorage
    arguments:
      - '@database'
  logger.dblog_persistent:
    class: Drupal\dblog_persistent\Logger\DbLogPersistent
    arguments:
      - '@database'
      - '@logger.log_message_parser'
      - '@entity_type.manager'
      - '@dblog_persistent.storage'
    tags:
      - { name: logger }

As a hack, I could surround every function in the logger with ifs that ensure it doesn't run unless installation is complete, but that's pretty dirty. Is there at least some kind of null entity storage that the constructor could fall back on, to minimize the amount of defensive programming?

I created a logger service that uses a config entity for configuration: https://drupal.org/project/dblog_persistent

Unfortunately, it appears that this module is not installable on a new site, because Drupal attempts to instantiate the logger service before actually installing the config entity type it depends on - the result is an InvalidPluginDefinitionException.

There has to be some way to prevent services from being instantiated until the module is installed, or not?

This is the class and constructor definition:

<?php

namespace Drupal\dblog_persistent\Logger;

use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Config\Entity\ConfigEntityStorage;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Logger\LogMessageParserInterface;
use Drupal\dblog\Logger\DbLog;
use Drupal\dblog_persistent\DbLogPersistentStorageInterface;

/**
 * Class DbLogPersistent
 *
 * @package Drupal\dblog_persistent\Logger
 */
class DbLogPersistent extends DbLog {

  /**
   * @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
   */
  protected $channelStorage;

  /**
   * @var \Drupal\dblog_persistent\DbLogPersistentStorageInterface
   */
  private $storage;

  /**
   * @var \Drupal\dblog_persistent\Entity\ChannelInterface[]
   */
  private $channels;

  public function __construct(Connection $connection,
                              LogMessageParserInterface $parser,
                              EntityTypeManagerInterface $manager,
                              DbLogPersistentStorageInterface $storage) {
    parent::__construct($connection, $parser);
    // The following causes an error on installation:
    $this->channelStorage = $manager->getStorage('dblog_persistent_channel');
    $this->storage = $storage;
  }

And the service definition:

services:
  dblog_persistent.storage:
    class: Drupal\dblog_persistent\DbLogPersistentStorage
    arguments:
      - '@database'
  logger.dblog_persistent:
    class: Drupal\dblog_persistent\Logger\DbLogPersistent
    arguments:
      - '@database'
      - '@logger.log_message_parser'
      - '@entity_type.manager'
      - '@dblog_persistent.storage'
    tags:
      - { name: logger }

As a hack, I could surround every function in the logger with ifs that ensure it doesn't run unless installation is complete, but that's pretty dirty. Is there at least some kind of null entity storage that the constructor could fall back on, to minimize the amount of defensive programming?

I created a logger service that uses a config entity for configuration: https://drupal.org/project/dblog_persistent

Unfortunately, it appears that this module is not installable on a new site, because Drupal attempts to instantiate the logger service before actually installing the config entity type it depends on - the result is a PluginNotFoundException.

There has to be some way to prevent services from being instantiated until the module is installed, or not?

This is the class and constructor definition:

<?php

namespace Drupal\dblog_persistent\Logger;

use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Config\Entity\ConfigEntityStorage;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Logger\LogMessageParserInterface;
use Drupal\dblog\Logger\DbLog;
use Drupal\dblog_persistent\DbLogPersistentStorageInterface;

/**
 * Class DbLogPersistent
 *
 * @package Drupal\dblog_persistent\Logger
 */
class DbLogPersistent extends DbLog {

  /**
   * @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
   */
  protected $channelStorage;

  /**
   * @var \Drupal\dblog_persistent\DbLogPersistentStorageInterface
   */
  private $storage;

  /**
   * @var \Drupal\dblog_persistent\Entity\ChannelInterface[]
   */
  private $channels;

  public function __construct(Connection $connection,
                              LogMessageParserInterface $parser,
                              EntityTypeManagerInterface $manager,
                              DbLogPersistentStorageInterface $storage) {
    parent::__construct($connection, $parser);
    // The following causes an error on installation:
    $this->channelStorage = $manager->getStorage('dblog_persistent_channel');
    $this->storage = $storage;
  }

And the service definition:

services:
  dblog_persistent.storage:
    class: Drupal\dblog_persistent\DbLogPersistentStorage
    arguments:
      - '@database'
  logger.dblog_persistent:
    class: Drupal\dblog_persistent\Logger\DbLogPersistent
    arguments:
      - '@database'
      - '@logger.log_message_parser'
      - '@entity_type.manager'
      - '@dblog_persistent.storage'
    tags:
      - { name: logger }

As a hack, I could surround every function in the logger with ifs that ensure it doesn't run unless installation is complete, but that's pretty dirty. Is there at least some kind of null entity storage that the constructor could fall back on, to minimize the amount of defensive programming?

Source Link

Avoiding entity-type errors on module installation

I created a logger service that uses a config entity for configuration: https://drupal.org/project/dblog_persistent

Unfortunately, it appears that this module is not installable on a new site, because Drupal attempts to instantiate the logger service before actually installing the config entity type it depends on - the result is an InvalidPluginDefinitionException.

There has to be some way to prevent services from being instantiated until the module is installed, or not?

This is the class and constructor definition:

<?php

namespace Drupal\dblog_persistent\Logger;

use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Config\Entity\ConfigEntityStorage;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Logger\LogMessageParserInterface;
use Drupal\dblog\Logger\DbLog;
use Drupal\dblog_persistent\DbLogPersistentStorageInterface;

/**
 * Class DbLogPersistent
 *
 * @package Drupal\dblog_persistent\Logger
 */
class DbLogPersistent extends DbLog {

  /**
   * @var \Drupal\Core\Config\Entity\ConfigEntityStorageInterface
   */
  protected $channelStorage;

  /**
   * @var \Drupal\dblog_persistent\DbLogPersistentStorageInterface
   */
  private $storage;

  /**
   * @var \Drupal\dblog_persistent\Entity\ChannelInterface[]
   */
  private $channels;

  public function __construct(Connection $connection,
                              LogMessageParserInterface $parser,
                              EntityTypeManagerInterface $manager,
                              DbLogPersistentStorageInterface $storage) {
    parent::__construct($connection, $parser);
    // The following causes an error on installation:
    $this->channelStorage = $manager->getStorage('dblog_persistent_channel');
    $this->storage = $storage;
  }

And the service definition:

services:
  dblog_persistent.storage:
    class: Drupal\dblog_persistent\DbLogPersistentStorage
    arguments:
      - '@database'
  logger.dblog_persistent:
    class: Drupal\dblog_persistent\Logger\DbLogPersistent
    arguments:
      - '@database'
      - '@logger.log_message_parser'
      - '@entity_type.manager'
      - '@dblog_persistent.storage'
    tags:
      - { name: logger }

As a hack, I could surround every function in the logger with ifs that ensure it doesn't run unless installation is complete, but that's pretty dirty. Is there at least some kind of null entity storage that the constructor could fall back on, to minimize the amount of defensive programming?