ACF Global Options and Metaboxes for WP Multisite

…или как сделать так, чтобы набор метаполей и/или ACF Option Page был единым для всех блогов в рамках установки WordPress Multisite.

У меня проблема возникла, когда на мультисайте существующие глобальные настройки (Options Page) должны были стать действительно глобальными. Я пошел дальше и сделал все настройки метабоксов, включая Options Page, едиными для всех блогов.

Другими словами, при изменении набора настроек ACF главного сайта, следует избежать необходимости вручную вносить одни и те же правки во всех блогах.

Также, при переносе файлов сайта с девелоперского домена на предпрод, БД, как правило, подтягивается с прода. А значит, набор метаполей ACF может различаться.

Подход к решению таков:

  1. в главном блоге установки в ACF-панели настраиваем необходимые метаполя и ACF Option Page
  2. во всех прочих блогах ничего не создаем или удаляем, если они уже есть
  3. при сохранении настроек ACF главного блога создаем php-файл импорта настроек для блогов
  4. загружаем созданный файл, если текущий блог не главный.

Код для п.3. Можно прямо в functions.php

<?php
add_action( 'shutdown', 'sh_acf_generate' );

function sh_acf_generate(){
  global $wpdb;
  
  if ( ! did_action( 'save_post_acf-field-group' ) ) return;
  
  $fields = $wpdb->get_col( "SELECT post_name FROM {$wpdb->posts} WHERE post_type = 'acf-field-group' AND post_status = 'publish'" );
  
  if ( empty( $fields ) ) return; 
  
  $str_replace = array(
    "  "      => "\t",
    "'!!__(!!\'"  => "__('",
    "!!\', !!\'"  => "', '",
    "!!\')!!'"    => "')",
    "array ("    => "array("
  );
  $preg_replace = array(
    '/([\t\r\n]+?)array/'  => 'array',
    '/[0-9]+ => array/'    => 'array'
  );
  
  $out = "<?php if( function_exists('acf_add_local_field_group') ):" . "\r\n" . "\r\n";
  
  foreach( $fields as $f ) :
  
    $field_group = acf_get_field_group( $f );
    // load fields
    $field_group['fields'] = acf_get_fields( $field_group );
    // prepare for export
    $field_group = acf_prepare_field_group_for_export( $field_group );
  
    $code = var_export( $field_group, true );
    // change double spaces to tabs
    $code = str_replace( array_keys($str_replace), array_values($str_replace), $code );
    // correctly formats "=> array("
    $code = preg_replace( array_keys($preg_replace), array_values($preg_replace), $code );
    // esc_textarea
    $code = esc_textarea( $code );
    $out .= "acf_add_local_field_group({$code});" . "\r\n" . "\r\n";
  endforeach;
  
  $out .= "endif;";
  
  file_put_contents( get_template_directory() . '/inc/acf.php', htmlspecialchars_decode( $out, ENT_QUOTES  ) );
}

Данный код является вырезкой из метода html_generate() класса ACF_Admin_Tool_Export. Никаких хуков найдено не было, поэтому пришлось копировать код.

На данном этапе мы отлавливаем момент сохранения настроек и, после некоторой обработки, сохраняем php-код импорта этих настроек.

Почему используем хук shutdown, чтобы ACF успел создать/удалить новые acf-field-group-записи при их создании/удалении.

Теперь остаётся только подключить сгенерированный файл в function.php, предварительно убедившись, что делаем это для всех блогов, кроме главного.

<?php

if ( 1 != get_current_blog_id() ):
  include get_template_directory() . '/inc/acf.php';
endif;

 

Для использования при миграции файлов с девелоперского домена, добавляем проверку текущего домена с помощью функции get_home_url().

Share this post



Отправить ответ

Оставьте первый комментарий!