class FeaturesAssigner in Features 8.4
Same name and namespace in other branches
- 8.3 src/FeaturesAssigner.php \Drupal\features\FeaturesAssigner
Class responsible for performing package assignment.
Hierarchy
- class \Drupal\features\FeaturesAssigner implements FeaturesAssignerInterface uses StringTranslationTrait
Expanded class hierarchy of FeaturesAssigner
1 string reference to 'FeaturesAssigner'
1 service uses FeaturesAssigner
File
- src/
FeaturesAssigner.php, line 15
Namespace
Drupal\featuresView source
class FeaturesAssigner implements FeaturesAssignerInterface {
use StringTranslationTrait;
/**
* The package assignment method plugin manager.
*
* @var \Drupal\Component\Plugin\PluginManagerInterface
*/
protected $assignerManager;
/**
* The features manager.
*
* @var \Drupal\features\FeaturesManagerInterface
*/
protected $featuresManager;
/**
* The configuration factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* The configuration storage.
*
* @var \Drupal\Core\Config\StorageInterface
*/
protected $configStorage;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Local cache for package assignment method instances.
*
* @var array
*/
protected $methods;
/**
* Bundles.
*
* @var \Drupal\features\FeaturesBundleInterface[]
*/
protected $bundles;
/**
* Currently active bundle.
*
* @var \Drupal\features\FeaturesBundleInterface
*/
protected $currentBundle;
/**
* The name of the currently active installation profile.
*
* @var string
*/
protected $installProfile;
/**
* Constructs a new FeaturesAssigner object.
*
* @param \Drupal\features\FeaturesManagerInterface $features_manager
* The features manager.
* @param \Drupal\Component\Plugin\PluginManagerInterface $assigner_manager
* The package assignment methods plugin manager.
* @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\StorageInterface $config_storage
* The configuration factory.
* @param string $install_profile
* The name of the currently active installation profile.
*/
public function __construct(FeaturesManagerInterface $features_manager, PluginManagerInterface $assigner_manager, EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory, StorageInterface $config_storage, $install_profile) {
$this->featuresManager = $features_manager;
$this->assignerManager = $assigner_manager;
$this->entityTypeManager = $entity_type_manager;
$this->configFactory = $config_factory;
$this->configStorage = $config_storage;
$this->installProfile = $install_profile;
$this->bundles = $this
->getBundleList();
$this->currentBundle = $this
->getBundle(FeaturesBundleInterface::DEFAULT_BUNDLE);
// Ensure bundle information is fresh.
$this
->createBundlesFromPackages();
}
/**
* Initializes the injected features manager with the assigner.
*
* This should be called right after instantiating the assigner to make it
* available to the features manager without introducing a circular
* dependency.
*/
public function initFeaturesManager() {
$this->featuresManager
->setAssigner($this);
}
/**
* {@inheritdoc}
*/
public function reset() {
$this->methods = [];
$this->featuresManager
->reset();
}
/**
* Gets enabled assignment methods.
*
* @return array
* An array of enabled assignment methods, sorted by weight.
*/
public function getEnabledAssigners() {
$enabled = $this->currentBundle
->getEnabledAssignments();
$weights = $this->currentBundle
->getAssignmentWeights();
foreach ($enabled as $key => $value) {
$enabled[$key] = $weights[$key];
}
asort($enabled);
return $enabled;
}
/**
* Clean up the package list after all config has been assigned.
*/
protected function cleanup() {
$packages = $this->featuresManager
->getPackages();
foreach ($packages as $index => $package) {
if ($package
->getStatus() === FeaturesManagerInterface::STATUS_NO_EXPORT && empty($package
->getConfig()) && empty($package
->getConfigOrig())) {
unset($packages[$index]);
}
}
$this->featuresManager
->setPackages($packages);
}
/**
* {@inheritdoc}
*/
public function assignConfigPackages($force = FALSE) {
foreach ($this
->getEnabledAssigners() as $method_id => $info) {
$this
->applyAssignmentMethod($method_id, $force);
}
$this
->cleanup();
}
/**
* {@inheritdoc}
*/
public function applyAssignmentMethod($method_id, $force = FALSE) {
$this
->getAssignmentMethodInstance($method_id)
->assignPackages($force);
}
/**
* {@inheritdoc}
*/
public function getAssignmentMethods() {
return $this->assignerManager
->getDefinitions();
}
/**
* Returns an instance of the specified package assignment method.
*
* @param string $method_id
* The string identifier of the package assignment method to use to package
* configuration.
*
* @return \Drupal\features\FeaturesAssignmentMethodInterface
* The package assignment method instance.
*/
protected function getAssignmentMethodInstance($method_id) {
if (!isset($this->methods[$method_id])) {
$instance = $this->assignerManager
->createInstance($method_id, []);
$instance
->setFeaturesManager($this->featuresManager);
$instance
->setAssigner($this);
$instance
->setEntityTypeManager($this->entityTypeManager);
$instance
->setConfigFactory($this->configFactory);
$this->methods[$method_id] = $instance;
}
return $this->methods[$method_id];
}
/**
* {@inheritdoc}
*/
public function purgeConfiguration() {
// Ensure that we are getting the defined package assignment information.
// An invocation of \Drupal\Core\Extension\ModuleHandler::install() or
// \Drupal\Core\Extension\ModuleHandler::uninstall() could invalidate the
// cached information.
$this->assignerManager
->clearCachedDefinitions();
$this->featuresManager
->reset();
}
/**
* {@inheritdoc}
*/
public function getBundle($name = NULL) {
if (empty($name)) {
return $this->currentBundle;
}
elseif (isset($this->bundles[$name])) {
return $this->bundles[$name];
}
return NULL;
}
/**
* {@inheritdoc}
*/
public function setBundle(FeaturesBundleInterface $bundle, $current = TRUE) {
$this->bundles[$bundle
->getMachineName()] = $bundle;
if (isset($this->currentBundle) && ($current || $bundle
->getMachineName() == $this->currentBundle
->getMachineName())) {
$this->currentBundle = $bundle;
}
}
/**
* {@inheritdoc}
*/
public function findBundle(array $info, $features_info = NULL) {
$bundle = NULL;
if (!empty($features_info['bundle'])) {
$bundle = $this
->getBundle($features_info['bundle']);
}
elseif (!empty($info['package'])) {
$bundle = $this
->findBundleByName($info['package']);
}
if (!isset($bundle)) {
// Return the default bundle.
return $this
->getBundle(FeaturesBundleInterface::DEFAULT_BUNDLE);
}
return $bundle;
}
/**
* {@inheritdoc}
*/
public function setCurrent(FeaturesBundleInterface $bundle) {
$this->currentBundle = $bundle;
$session = \Drupal::request()
->getSession();
if (isset($session)) {
$session
->set('features_current_bundle', $bundle
->getMachineName());
}
return $bundle;
}
/**
* {@inheritdoc}
*/
public function getBundleList() {
if (empty($this->bundles)) {
$this->bundles = [];
foreach ($this->entityTypeManager
->getStorage('features_bundle')
->loadMultiple() as $machine_name => $bundle) {
$this->bundles[$machine_name] = $bundle;
}
}
return $this->bundles;
}
/**
* {@inheritdoc}
*/
public function findBundleByName($name, $create = FALSE) {
$bundles = $this
->getBundleList();
foreach ($bundles as $machine_name => $bundle) {
if ($name == $bundle
->getName()) {
return $bundle;
}
}
$machine_name = strtolower(str_replace([
' ',
'-',
], '_', $name));
if (isset($bundles[$machine_name])) {
return $bundles[$machine_name];
}
return NULL;
}
/**
* {@inheritdoc}
*/
public function createBundleFromDefault($machine_name, $name = NULL, $description = NULL, $is_profile = FALSE, $profile_name = NULL) {
// Duplicate the default bundle to get its default configuration.
$default = $this
->getBundle(FeaturesBundleInterface::DEFAULT_BUNDLE);
if (!$default) {
// If we don't have the default installed, generate it from the install
// config file.
$ext_storage = new ExtensionInstallStorage($this->configStorage, ExtensionInstallStorage::CONFIG_INSTALL_DIRECTORY, ExtensionInstallStorage::DEFAULT_COLLECTION, TRUE, $this->installProfile);
$record = $ext_storage
->read('features.bundle.default');
$bundle_storage = $this->entityTypeManager
->getStorage('features_bundle');
$default = $bundle_storage
->createFromStorageRecord($record);
}
/** @var \Drupal\features\Entity\FeaturesBundle $bundle */
$bundle = $default
->createDuplicate();
$bundle
->setMachineName($machine_name);
$name = !empty($name) ? $name : $machine_name;
$bundle
->setName($name);
if (isset($description)) {
$bundle
->setDescription($description);
}
else {
$bundle
->setDescription(t('Auto-generated bundle from package @name', [
'@name' => $name,
]));
}
$bundle
->setIsProfile($is_profile);
if (isset($profile_name)) {
$bundle
->setProfileName($profile_name);
}
$bundle
->save();
$this
->setBundle($bundle);
return $bundle;
}
/**
* {@inheritdoc}
*/
public function createBundlesFromPackages() {
$existing_bundles = $this
->getBundleList();
$new_bundles = [];
// Only parse from installed features.
$modules = $this->featuresManager
->getFeaturesModules(NULL, TRUE);
foreach ($modules as $module) {
$info = $this->featuresManager
->getExtensionInfo($module);
// @todo This entire function could be simplified a lot using packages.
$features_info = $this->featuresManager
->getFeaturesInfo($module);
// Create a new bundle if:
// - the feature specifies a bundle and
// - that bundle doesn't yet exist locally.
// Allow profiles to override previous values.
if (!empty($features_info['bundle']) && !isset($existing_bundles[$features_info['bundle']]) && (!in_array($features_info['bundle'], $new_bundles) || $info['type'] == 'profile')) {
if ($info['type'] == 'profile') {
$new_bundle = [
'name' => $info['name'],
'description' => $info['description'],
'is_profile' => TRUE,
'profile_name' => $module
->getName(),
];
}
else {
$new_bundle = [
'name' => isset($info['package']) ? $info['package'] : ucwords(str_replace('_', ' ', $features_info['bundle'])),
'description' => NULL,
'is_profile' => FALSE,
'profile_name' => NULL,
];
}
$new_bundle['machine_name'] = $features_info['bundle'];
$new_bundles[$new_bundle['machine_name']] = $new_bundle;
}
}
foreach ($new_bundles as $new_bundle) {
$this
->createBundleFromDefault($new_bundle['machine_name'], $new_bundle['name'], $new_bundle['description'], $new_bundle['is_profile']);
}
}
/**
* {@inheritdoc}
*/
public function getBundleOptions() {
$list = $this
->getBundleList();
$result = [];
foreach ($list as $machine_name => $bundle) {
$result[$machine_name] = $bundle
->getName();
}
return $result;
}
/**
* {@inheritdoc}
*/
public function applyBundle($machine_name = NULL) {
$this
->reset();
$bundle = $this
->loadBundle($machine_name);
if (isset($bundle)) {
$this
->assignConfigPackages();
return $this->currentBundle;
}
return NULL;
}
/**
* {@inheritdoc}
*/
public function renameBundle($old_machine, $new_machine) {
$is_current = isset($this->currentBundle) && $old_machine == $this->currentBundle
->getMachineName();
$bundle = $this
->getBundle($old_machine);
if ($bundle
->getMachineName() != '') {
// Remove old bundle from the list if it's not the Default bundle.
unset($this->bundles[$old_machine]);
}
$bundle
->setMachineName($new_machine);
$this
->setBundle($bundle);
// Put the bundle into the list with the correct name.
$this->bundles[$bundle
->getMachineName()] = $bundle;
if ($is_current) {
$this
->setCurrent($bundle);
}
return $bundle;
}
/**
* {@inheritdoc}
*/
public function loadBundle($machine_name = NULL) {
if (!isset($machine_name)) {
$session = \Drupal::request()
->getSession();
if (isset($session)) {
$machine_name = isset($session) ? $session
->get('features_current_bundle', FeaturesBundleInterface::DEFAULT_BUNDLE) : FeaturesBundleInterface::DEFAULT_BUNDLE;
}
}
$bundle = $this
->getBundle($machine_name);
if (!isset($bundle)) {
// If bundle no longer exists then return default.
$bundle = $this->bundles[FeaturesBundleInterface::DEFAULT_BUNDLE];
}
return $this
->setCurrent($bundle);
}
/**
* {@inheritdoc}
*/
public function removeBundle($machine_name) {
$bundle = $this
->getBundle($machine_name);
if (isset($bundle) && !$bundle
->isDefault()) {
unset($this->bundles[$machine_name]);
$bundle
->remove();
}
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
FeaturesAssigner:: |
protected | property | The package assignment method plugin manager. | |
FeaturesAssigner:: |
protected | property | Bundles. | |
FeaturesAssigner:: |
protected | property | The configuration factory. | |
FeaturesAssigner:: |
protected | property | The configuration storage. | |
FeaturesAssigner:: |
protected | property | Currently active bundle. | |
FeaturesAssigner:: |
protected | property | The entity type manager. | |
FeaturesAssigner:: |
protected | property | The features manager. | |
FeaturesAssigner:: |
protected | property | The name of the currently active installation profile. | |
FeaturesAssigner:: |
protected | property | Local cache for package assignment method instances. | |
FeaturesAssigner:: |
public | function |
Applies a given package assignment method. Overrides FeaturesAssignerInterface:: |
|
FeaturesAssigner:: |
public | function |
Makes the named bundle the current bundle. Overrides FeaturesAssignerInterface:: |
|
FeaturesAssigner:: |
public | function |
Apply all enabled package assignment methods. Overrides FeaturesAssignerInterface:: |
|
FeaturesAssigner:: |
protected | function | Clean up the package list after all config has been assigned. | |
FeaturesAssigner:: |
public | function |
Creates a new bundle by duplicating the default bundle and customizing. Overrides FeaturesAssignerInterface:: |
|
FeaturesAssigner:: |
public | function |
Creates bundles by parsing information from installed packages. Overrides FeaturesAssignerInterface:: |
|
FeaturesAssigner:: |
public | function |
Searches for a bundle that matches the $info.yml or $features.yml export. Overrides FeaturesAssignerInterface:: |
|
FeaturesAssigner:: |
public | function |
Returns a named bundle. Overrides FeaturesAssignerInterface:: |
|
FeaturesAssigner:: |
protected | function | Returns an instance of the specified package assignment method. | |
FeaturesAssigner:: |
public | function |
Returns the enabled package assignment methods. Overrides FeaturesAssignerInterface:: |
|
FeaturesAssigner:: |
public | function |
Returns a FeaturesBundle object. Overrides FeaturesAssignerInterface:: |
|
FeaturesAssigner:: |
public | function |
Returns an array of all existing features bundles. Overrides FeaturesAssignerInterface:: |
|
FeaturesAssigner:: |
public | function |
Returns an array of bundle names suitable for a select option list. Overrides FeaturesAssignerInterface:: |
|
FeaturesAssigner:: |
public | function | Gets enabled assignment methods. | |
FeaturesAssigner:: |
public | function | Initializes the injected features manager with the assigner. | |
FeaturesAssigner:: |
public | function |
Loads a named bundle. Overrides FeaturesAssignerInterface:: |
|
FeaturesAssigner:: |
public | function |
Resaves the configuration to purge missing assignment methods. Overrides FeaturesAssignerInterface:: |
|
FeaturesAssigner:: |
public | function | ||
FeaturesAssigner:: |
public | function |
Renames a bundle. Overrides FeaturesAssignerInterface:: |
|
FeaturesAssigner:: |
public | function |
Resets the assigned packages and the method instances. Overrides FeaturesAssignerInterface:: |
|
FeaturesAssigner:: |
public | function |
Stores a features bundle. Overrides FeaturesAssignerInterface:: |
|
FeaturesAssigner:: |
public | function |
Sets the currently active bundle. Overrides FeaturesAssignerInterface:: |
|
FeaturesAssigner:: |
public | function | Constructs a new FeaturesAssigner object. | |
FeaturesAssignerInterface:: |
constant | The package assignment method id for the package assigner itself. | ||
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |