Problem/Motivation
PHP 8 allows us to significantly reduce boilerplate in OO classes with injected services.
PHP 7:
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The entity repository.
*
* @var \Drupal\Core\Entity\EntityRepositoryInterface
*/
protected $entityRepository;
/**
* The configuration factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* The typed config manager.
*
* @var \Drupal\Core\Config\TypedConfigManagerInterface
*/
protected $typedConfigManager;
/**
* The active configuration storage.
*
* @var \Drupal\Core\Config\StorageInterface
*/
protected $activeStorage;
/**
* The event dispatcher.
*
* @var \Symfony\Contracts\EventDispatcher\EventDispatcherInterface
*/
protected $eventDispatcher;
/**
* The extension path resolver.
*
* @var \Drupal\Core\Extension\ExtensionPathResolver
*/
protected $extensionPathResolver;
/**
* Creates ConfigManager objects.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The configuration factory.
* @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager
* The typed config manager.
* @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
* The string translation service.
* @param \Drupal\Core\Config\StorageInterface $active_storage
* The active configuration storage.
* @param \Symfony\Contracts\EventDispatcher\EventDispatcherInterface $event_dispatcher
* The event dispatcher.
* @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
* The entity repository.
* @param \Drupal\Core\Extension\ExtensionPathResolver $extension_path_resolver
* The extension path resolver.
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory, TypedConfigManagerInterface $typed_config_manager, TranslationInterface $string_translation, StorageInterface $active_storage, EventDispatcherInterface $event_dispatcher, EntityRepositoryInterface $entity_repository, ExtensionPathResolver $extension_path_resolver) {
$this->entityTypeManager = $entity_type_manager;
$this->configFactory = $config_factory;
$this->typedConfigManager = $typed_config_manager;
$this->stringTranslation = $string_translation;
$this->activeStorage = $active_storage;
$this->eventDispatcher = $event_dispatcher;
$this->entityRepository = $entity_repository;
$this->extensionPathResolver = $extension_path_resolver;
}
vs PHP 8:
public function __construct(
protected EntityTypeManagerInterface $entityTypeManager,
protected ConfigFactoryInterface $configFactory,
protected TypedConfigManagerInterface $typedConfigManager,
protected TranslationInterface $stringTranslation,
protected StorageInterface $activeStorage,
protected EventDispatcherInterface $eventDispatcher,
protected EntityRepositoryInterface $entityRepository,
protected ExtensionPathResolver $extensionPathResolver,
) {}
Steps to reproduce
Proposed resolution
Before running rector, you need to comment out a line in the rector config class otherwise the @var docs will be copied into the constructor signature which is extremely ugly.
Comment out this line:
$this->propertyPromotionDocBlockMerger->mergePropertyAndParamDocBlocks($property, $param, $paramTagValueNode);
1. Run the following rector:
<?php
declare(strict_types=1);
use Rector\Config\RectorConfig;
use Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector;
return static function (RectorConfig $rectorConfig): void {
$rectorConfig->paths([
__DIR__ . '/app/composer',
__DIR__ . '/app/core',
]);
$rectorConfig->ruleWithConfiguration(ClassPropertyAssignToConstructorPromotionRector::class, [
ClassPropertyAssignToConstructorPromotionRector::INLINE_PUBLIC => TRUE,
]);
$rectorConfig->parallel(processTimeout: 300, maxNumberOfProcess: 4);
};
2. Rector will put the opening brace of the constructor onto a new line. To fix this run phpcbf with just the relevant sniff:
./bin/phpcbf --standard=app/core/phpcs.xml.dist --sniffs=Drupal.Functions.MultiLineFunctionDeclaration app/[core|composer]
Do not try to rebase the MR, simply run the steps again.
Remaining tasks
Write a rector rule to help us with this.
Decide if we need to document constructor parameters any more or if that is also unnecessary boilerplate.
Discover any edge cases and figure out what to do with them.
User interface changes
API changes
Data model changes
Release notes snippet