Bir modülün yapılandırmasını nasıl güncellerim?


33

Drupal 8'de özel bir modül yapıyorum. Bazı YAML yapılandırma dosyalarını içeriyor.

Geliştikçe, yapılandırmamı değiştirmem ve eklemeliyim, örneğin özel varlığım üzerine başka bir alan eklemek için.

Şu anda Drupal’ın değişiklikleri fark etmesini sağlamanın tek yolu modülü kaldırmak ve yeniden kurmak.

Modüller tarafından sağlanan konfigürasyon dosyalarının aktif konfigürasyon ile aynı olup olmadığını kontrol etmek için Drupal'ı almanın bir yolu var mı? Modül güncellemeleri nasıl yapılır? D7'de hook_update_NPHP kullanarak alan eklemek için kullanılır, ancak bunun D8'deki CM tarafından ele alınması gerektiği gibi görünüyor?

Modüldeki yml dosyalarını güncelledikten sonra denediklerim:

  1. drush cryapılandırma senkronizasyonu.

  2. tüm güncellenmiş konfigürasyon dosyalarının elle kopyalanması sites/default/files/config_XXX/staging/- ancak bu şu hatayı veriyor: "Aşamalı konfigürasyon alınamaz çünkü bu siteden farklı bir siteden geliyor. Konfigürasyonu sadece bu sitenin klonlanmış örnekleri arasında senkronize edebilirsiniz." .

  3. config yöneticisini kullanarak dosyaları tek tek el ile almak. Bu işe yarıyor, ama belli ki daha otomatik bir yol olmalı.

  4. [EDIT] değişiklikleri incelemek ve config modülüne 'geri dönmek' için config_update modülünü manuel olarak kullanın . Yine, bu manuel.

DÜZENLEME: Gönderen yapılandırmayı yönetme - yapılması ve yapılmaması gerekenler

YAPILMAMASI GEREKENLER

Bir modülün config / install dizinindeki dosyaları değiştirerek sitenizdeki aktif konfigürasyonu değiştirmeyi deneyin. Bu çalışmayacak çünkü Drupal sadece modül kurulduğunda bu dizinden okuyacak.

... ama orada değiştirir edilir gidiş modülleri onlar onların ilk serbest gerekli konfigürasyon dosyasında ne bağlı sürece gerçekleşmesi ve her zamankinden güncelleyebilir veya yapılandırma eklemek asla.

Şimdiden teşekkürler.


Daha önce çok benzer bir şey sorulduğunu düşünüyorum (şu anda tam olarak bulamıyorum) ve cevabın varsayılan konfigürasyonun sadece kurulum sırasında görüldüğü olduğunu düşünüyorum . Yine de bana alıntı yapmayın :)
Clive

1
'k, ama nasıl bir modül güncellenir? Modüllerin D8’de güncelleme almasına izin verilir, doğru ;-)? Modüller için "Drupal! Şimdi bu ekstra yapılandırmaya ihtiyacım var, bir göz atın ve lütfen içinde birleştirin" demenin bir yolu olmalı (la config_update).
artfulrobot

Yapılandırma Güncelleme Yöneticisi bu işi yapıyor, ancak bunu yapmanın yerel bir yolu olması gerektiğini düşünüyor. İçinde bir şey hook_update_Nvarsayardım, ama ne olduğundan emin değilim
Clive

2
Vay, bence cevabı "yapamazsın" olabilir! Bunun geldiğini asla görmedim! Geri dön hook_update_N. Drupal 8 hakkında küçük siteler için mükemmel bir makale (ve 2. bölüm ). D8'de "siteler kendi modüllerine değil kendilerine ait yapılandırmalara" sahiptir .
artfulrobot

Bunun için mükemmel bir kullanım durumu olduğunu belirtmek isterim ki, belirli konfigürasyon parçalarını paylaşmak, hepsini değil ve bunları dağıtmak istediğiniz çok siteli bir kurulumdur. Bunlar özel modüller içerebilir. Tek bir site için basitçe bir yapılandırma dışa aktarma / içe aktarma olacaktır, çoklu alan bu kadar basit olmazdı.
Ambidex

Yanıtlar:


24

Orijinal soruda ve takip yorumlarında belirtildiği gibi, bunu gerçekleştirmek için çeşitli katkı modülleri ve manuel yöntemler vardır.

Otomatik olarak veya özel bir şekilde yapmak için hook_update_N()hala en uygun seçenek olduğunu düşünüyorum .

Örneğin, bu, aşağıdakileri ayarlamak üzere güncellemek için Head 2 Head'den bir örnektir :system.sitedefault_langcode

  $config_factory = \Drupal::configFactory();
  $langcode = $config_factory->get('system.site')->get('langcode');
  $config_factory->getEditable('system.site')->set('default_langcode', $langcode)->save();

Ayrıca config de okuyabilirsiniz (yalnızca yeni konfigürasyon eklemek için önerilir, özelleştirilmesi gereken konfigürasyonu güncellemeniz veya geçersiz kılmanız gerekmez):

  $source = new FileStorage($path);
  /** @var \Drupal\Core\Config\StorageInterface $active_storage */
  $active_storage = \Drupal::service('config.storage');
  $active_storage->write($name, $source->read($name));

dosyanın $pathmutlak yolu nerede my_config.foo.yml?


1
İkinci yaklaşımı takip ederken config Drupal'a yazılmıştır ancak config dizinine verdiğimde bile UUID almıyorum. Bu beni özel bir Bakışla denedim bir soruna yol açıyor. Görüntülere genel bakış sayfası, bana Yapılandırma varlığı için kullanıcı kimliği bulunmadığından önemli bir hata verdi.
Sebastian,

9

Ben de bu soruya girdim ancak buradaki durumum için doğru cevabı bulamadım, başka bir cevap eklemek istiyorum.

Lütfen dikkat: Anti-desen ileride!

Kullanım durumda

Projeleri geliştirirken, test / kabul ortamımızı yeni konfigürasyon güncellemeleriyle sürekli güncelleriz. Örneğin basit bir kurgusal Haber modülü alın, modüle bir içerik türü eklemek ve bunu kabul ortamımıza dağıtmak istiyoruz. İncelemeden sonra, birkaç alanın eksik ve yapılandırmayla ilgili diğer şeylerin olduğu sonucuna vardık. Kabul ortamının config içinde güncellenmediğini bildiğimiz için, sadece tüm işlevselliği modülden yeniden yüklemek istiyoruz .yml.

Konfigürasyonlarımıza sadece çoklu siteler geliştirirken modüllerde ihtiyaç duyuyoruz. Tekli siteler için, çoğunlukla yalnızca sonraki adımın gereksiz olduğu ihraç edilen site yapılandırmasını kullanırız.

Reimport config tamamen (anti-patern!)

ConfigInstaller servisini kullanarak, config'nin tamamını belirli bir modülden tekrar alabileceğimizi gördük.

// Implement in a update_N hook. 
\Drupal::service('config.installer')->installDefaultConfig('module', $module);

Dikkatle kullanın!

Bunun, ortam içinde değiştirilmiş olan aktif içeriğin üzerine yazacağını eklemek isterim. Bu nedenle, bu çözümü yalnızca etkin yapılandırmanın üzerine yazmanın güvenli olduğundan eminseniz kullanın. Bunu asla bir üretim ortamında kullanmayacağız ve yalnızca erken gelişim için geçerli olacak.

Bunu düşünmeden önce ilk önce @ jhedstrom'un çözümünü deneyin.


9

Bulduğum bu Özü geri döner / yeniden drush kullanarak modülün yapılandırmasını verilen GitHub'dan, tarih:

drush cim -y --partial --source=modules/path/to/module/config/install/

2

Yorumuma göre: Bir modülün konfigürasyonunu nasıl güncellerim?

İkinci yaklaşımı takip ederken config Drupal'a yazılmıştır ancak config dizinine verdiğimde bile UUID almıyorum. Bu beni özel bir Bakışla denedim bir soruna yol açıyor. Görüntülere genel bakış sayfası, bana Yapılandırma varlığı için kullanıcı kimliği bulunmadığından önemli bir hata verdi.

Bu konuda bana yardımcı olan küçük bir işlev yarattım, işte örnek kodum:

function _example_views_update_config($configsNames) {
  $config_path    = drupal_get_path('module', 'example') . '/config/install';
  $source         = new FileStorage($config_path);
  $config_storage = \Drupal::service('config.storage');
  $config_factory = \Drupal::configFactory();
  $uuid_service = \Drupal::service('uuid');

  foreach ($configsNames as $name) {
    $config_storage->write($name, $source->read($name));
    $config_factory->getEditable($name)->set('uuid', $uuid_service->generate())->save();
  }
}

/**
 * Add new action configurations.
 */
function example_update_8003() {
  $configsNames = [
    'config-1',
    'config-2',
  ];

  _example_views_update_config($configsNames);
  return 'Added new configurations.';
}

1

Yukarıdaki cevap (tamamen yeniden içe aktarma) benim kullanım davam için de işe yaradı, ancak önce daha seçici bir yeniden içe aktarma işlemi için biraz zaman harcadım. İşte güncelleme kancası olarak çalışıyor gibiydi ve config_update modülündeki koda dayanıyordu:

/**
 * Update all my config.
 *
 * This can be more selective than calling installDefaultConfig().
 */
function MYMODULE_update_8004() {
  $prefixes = [
    'field.storage.node',
    'field.field.node',
    'node.type',
    'core.base_field_override.node',
    'core.entity_view_display'
  ];
  $results = [];
  foreach ($prefixes as $prefix) {
    $results[$prefix] = _update_or_install_config($prefix);
  }
  $return = '';
  foreach ($results as $prefix => $result) {
    $return .= "\n$prefix:\n";
    foreach ($result as $key => $ids) {
      $return .= "$key: " . implode(', ', $ids) . "\n";
    }
  }
  if (function_exists('drush_log')) {
    drush_log($return, \Psr\Log\LogLevel::WARNING);
  }
  return $return;
}


/**
 * Update or install config entities from config/install files.
 *
 * @see \Drupal\config_update\ConfigReverter::import
 * @see \Drupal\config_update\ConfigReverter::revert
 *
 * @param string $prefix
 *   The prefix for YAML files in find, like 'field.storage.node'
 */
function _update_or_install_config($prefix) {
  $updated = [];
  $created = [];
  /** @var \Drupal\Core\Config\ConfigManagerInterface $config_manger */
  $config_manger = \Drupal::service('config.manager');
  $files = glob(__DIR__ . '/config/install/' . $prefix . '.*.yml');
  foreach ($files as $file) {
    $raw = file_get_contents($file);
    $value = \Drupal\Component\Serialization\Yaml::decode($raw);
    if (!is_array($value)) {
      throw new \RuntimeException(sprintf('Invalid YAML file %s'), $file);
    }
    // Lazy hack here since that code ignores the file extension.
    $type = $config_manger->getEntityTypeIdByName(basename($file));
    $entity_manager = $config_manger->getEntityManager();
    $definition = $entity_manager->getDefinition($type);
    $id_key = $definition->getKey('id');
    $id = $value[$id_key];
    /** @var \Drupal\Core\Config\Entity\ConfigEntityStorage $entity_storage */
    $entity_storage = $entity_manager->getStorage($type);
    $entity = $entity_storage->load($id);
    if ($entity) {
      $entity = $entity_storage->updateFromStorageRecord($entity, $value);
      $entity->save();
      $updated[] = $id;
    }
    else {
      $entity = $entity_storage->createFromStorageRecord($value);
      $entity->save();
      $created[] = $id;
    }
  }
  return [
    'updated' => $updated,
    'created' => $created,
  ];
}

1

Yapılandırma Eşitleyici modülü, bu sorunu güzel bir şekilde çözmenize yardımcı olur. 7 modülün bu modül paketi, sadece bu durum için biraz fazla göze çarpıyor gibi görünüyor (niyeti esas olarak kişiselleştirmelerin üzerine yazmadan güncelleştirmelerde güvenli bir şekilde birleştirme yapmaktır), ancak konsepti nedeniyle modülün / kurulumun yapılandırma değişikliklerini izlemesine ve içe aktarmasına izin veriyor. / isteğe bağlı klasörler hızlı.

Temel olarak, aşağıdaki gibi test edebilirsiniz:

  • / config / install klasörüne yerleştirilen bazı "varsayılan" yapılandırma öğeleriyle yerel ortamınızda özel modülünüzü oluşturun ve etkinleştirin
  • config_sync modülünü ve tüm bağımlı modüllerini kurun ve etkinleştirin
  • modülünüzün config öğesinde / config / install klasörü içinde bazı düzenlemeler yapın.
  • erişim / admin / config / development / configuration / distro. Değişikliğinizi görmeli ve etkin konfigürasyona aktarma seçeneğine sahip olmalısınız (Birleştirme modu müşteri değişikliklerini korumaya yöneliktir, Sıfırlama modu içe aktarmaya zorlar) - geliştirme sırasında çoğunlukla Sıfırlama modunu kullanacağım, ancak birleştirme modu siz çalışmadıkça da çalışmalıdır. paralel olarak aynı konfigürasyonda herhangi bir manuel değişiklik yaptı

Not: config_sync işlevini yalnızca modülün geliştirilmesi sırasında yapılandırma içe aktarmasını hızlandırmak için kullanmak istiyorsanız (ve istemci güncellemeleriyle birleştirmek istemezseniz), bu paketi yalnızca yerel (geliştirme) ortamınıza yükleyip etkinleştirmeniz yeterlidir ( Modülünüzün sonlandırma işleminden sonra daha yüksek ortamlara gideceğini varsayalım ve yapılandırmasını daha yüksek ortamlara göndermek için D8 core config yönetimini kullanın).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.