View source
<?php
namespace Drupal\features;
use Drupal\Component\Plugin\PluginManagerInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\ExtensionInstallStorage;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
class FeaturesAssigner implements FeaturesAssignerInterface {
use StringTranslationTrait;
protected $assignerManager;
protected $featuresManager;
protected $configFactory;
protected $configStorage;
protected $entityTypeManager;
protected $methods;
protected $bundles;
protected $currentBundle;
protected $installProfile;
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);
$this
->createBundlesFromPackages();
}
public function initFeaturesManager() {
$this->featuresManager
->setAssigner($this);
}
public function reset() {
$this->methods = [];
$this->featuresManager
->reset();
}
public function getEnabledAssigners() {
$enabled = $this->currentBundle
->getEnabledAssignments();
$weights = $this->currentBundle
->getAssignmentWeights();
foreach ($enabled as $key => $value) {
$enabled[$key] = $weights[$key];
}
asort($enabled);
return $enabled;
}
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);
}
public function assignConfigPackages($force = FALSE) {
foreach ($this
->getEnabledAssigners() as $method_id => $info) {
$this
->applyAssignmentMethod($method_id, $force);
}
$this
->cleanup();
}
public function applyAssignmentMethod($method_id, $force = FALSE) {
$this
->getAssignmentMethodInstance($method_id)
->assignPackages($force);
}
public function getAssignmentMethods() {
return $this->assignerManager
->getDefinitions();
}
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];
}
public function purgeConfiguration() {
$this->assignerManager
->clearCachedDefinitions();
$this->featuresManager
->reset();
}
public function getBundle($name = NULL) {
if (empty($name)) {
return $this->currentBundle;
}
elseif (isset($this->bundles[$name])) {
return $this->bundles[$name];
}
return NULL;
}
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;
}
}
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 $this
->getBundle(FeaturesBundleInterface::DEFAULT_BUNDLE);
}
return $bundle;
}
public function setCurrent(FeaturesBundleInterface $bundle) {
$this->currentBundle = $bundle;
$session = \Drupal::request()
->getSession();
if (isset($session)) {
$session
->set('features_current_bundle', $bundle
->getMachineName());
}
return $bundle;
}
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;
}
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;
}
public function createBundleFromDefault($machine_name, $name = NULL, $description = NULL, $is_profile = FALSE, $profile_name = NULL) {
$default = $this
->getBundle(FeaturesBundleInterface::DEFAULT_BUNDLE);
if (!$default) {
$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);
}
$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;
}
public function createBundlesFromPackages() {
$existing_bundles = $this
->getBundleList();
$new_bundles = [];
$modules = $this->featuresManager
->getFeaturesModules(NULL, TRUE);
foreach ($modules as $module) {
$info = $this->featuresManager
->getExtensionInfo($module);
$features_info = $this->featuresManager
->getFeaturesInfo($module);
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']);
}
}
public function getBundleOptions() {
$list = $this
->getBundleList();
$result = [];
foreach ($list as $machine_name => $bundle) {
$result[$machine_name] = $bundle
->getName();
}
return $result;
}
public function applyBundle($machine_name = NULL) {
$this
->reset();
$bundle = $this
->loadBundle($machine_name);
if (isset($bundle)) {
$this
->assignConfigPackages();
return $this->currentBundle;
}
return NULL;
}
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() != '') {
unset($this->bundles[$old_machine]);
}
$bundle
->setMachineName($new_machine);
$this
->setBundle($bundle);
$this->bundles[$bundle
->getMachineName()] = $bundle;
if ($is_current) {
$this
->setCurrent($bundle);
}
return $bundle;
}
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)) {
$bundle = $this->bundles[FeaturesBundleInterface::DEFAULT_BUNDLE];
}
return $this
->setCurrent($bundle);
}
public function removeBundle($machine_name) {
$bundle = $this
->getBundle($machine_name);
if (isset($bundle) && !$bundle
->isDefault()) {
unset($this->bundles[$machine_name]);
$bundle
->remove();
}
}
}