224 lines
6.7 KiB
PHP
224 lines
6.7 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @author OnTheGo Systems
|
|
*/
|
|
class WPML_ACF_Xliff {
|
|
/** @var WPDB $wpdb */
|
|
public $wpdb;
|
|
/** @var SitePress $sitepress */
|
|
protected $sitepress;
|
|
|
|
private $search_patterns = array();
|
|
private $cache_key_for_fields_groups = 'get_acf_groups';
|
|
private $cache_group = 'wpml_acf';
|
|
|
|
/**
|
|
* WPML_ACF constructor.
|
|
*
|
|
* @param wpdb $wpdb
|
|
* @param SitePress $sitepress
|
|
*/
|
|
public function __construct( wpdb $wpdb, SitePress $sitepress ) {
|
|
$this->wpdb = $wpdb;
|
|
$this->sitepress = $sitepress;
|
|
}
|
|
|
|
public function init_hooks() {
|
|
add_action( 'save_post', array( $this, 'save_post' ), WPML_PRIORITY_BEFORE_EVERYTHING );
|
|
add_action( 'acf/update_field_group', array( $this, 'update_acf_field_group' ) );
|
|
}
|
|
|
|
public function save_post() {
|
|
if ( $this->is_updating_a_translatable_post_with_acf_fields() ) {
|
|
$this->search_patterns = array();
|
|
$fields = get_field_objects( $_POST['post_ID'] );
|
|
|
|
if ( $fields && is_array( $fields ) ) {
|
|
$this->update_custom_fields_settings( $fields );
|
|
$this->update_post_meta_settings();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
private function is_updating_a_translatable_post_with_acf_fields() {
|
|
return array_key_exists( 'post_type', $_POST )
|
|
&& array_key_exists( 'post_ID', $_POST )
|
|
&& array_key_exists( 'action', $_POST )
|
|
&& 'editpost' === $_POST['action']
|
|
&& array_key_exists( 'acf', $_POST )
|
|
&& is_array( $_POST['acf'] )
|
|
&& 'acf-field-group' !== $_POST['post_type']
|
|
&& $this->sitepress->is_translated_post_type( $_POST['post_type'] );
|
|
}
|
|
|
|
/**
|
|
* @param array $acf_fields
|
|
*/
|
|
private function update_custom_fields_settings( array $acf_fields ) {
|
|
$fields = $this->build_fields_names( $acf_fields );
|
|
foreach ( $fields as $field ) {
|
|
|
|
if ( array_key_exists( 'cf-names', $field ) && count( $field['cf-names'] ) ) {
|
|
$this->collect_meta_keys_to_update( '_' . $this->get_wildcards_field_name( $field ) );
|
|
}
|
|
if ( $this->is_a_container( $field ) ) {
|
|
$this->set_field_to_be_copied( $field['name'] );
|
|
$this->set_field_to_be_copied( '_' . $field['name'] );
|
|
$this->collect_meta_keys_to_update( $this->get_wildcards_field_name( $field ) );
|
|
}
|
|
|
|
if ( array_key_exists( 'sub_fields', $field ) ) {
|
|
foreach ( $field['sub_fields'] as $sub_field ) {
|
|
if ( $this->is_a_container( $sub_field ) && ( array_key_exists( 'cf-names', $sub_field ) && count( $sub_field['cf-names'] ) ) ) {
|
|
$this->collect_meta_keys_to_update( $this->get_wildcards_field_name( $sub_field ) );
|
|
}
|
|
|
|
$this->collect_meta_keys_to_update( '_' . $this->get_wildcards_field_name( $sub_field ) );
|
|
if ( $this->is_a_container( $sub_field ) ) {
|
|
$this->update_custom_fields_settings( $sub_field['sub_fields'] );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private function update_post_meta_settings() {
|
|
$conditions = count( $this->search_patterns );
|
|
|
|
if ( $conditions ) {
|
|
$this->search_patterns = array_unique( $this->search_patterns );
|
|
|
|
$sql_post_meta = "SELECT DISTINCT meta_key FROM {$this->wpdb->postmeta} WHERE ";
|
|
|
|
$sql_post_meta_where = array();
|
|
for ( $i = 0; $i < $conditions; $i ++ ) {
|
|
$sql_post_meta_where[] = 'meta_key LIKE %s';
|
|
}
|
|
$sql_post_meta .= implode( ' OR ', $sql_post_meta_where );
|
|
|
|
$sql = $this->wpdb->prepare( $sql_post_meta, $this->search_patterns );
|
|
|
|
$metas = $this->wpdb->get_col( $sql );
|
|
|
|
/** @var array $metas */
|
|
foreach ( $metas as $meta ) {
|
|
$this->set_field_to_be_copied( $meta );
|
|
}
|
|
|
|
$this->search_patterns = array();
|
|
}
|
|
}
|
|
|
|
private function build_fields_names( array $fields, array $parent_names = array() ) {
|
|
foreach ( $fields as $index => &$field ) {
|
|
$field_names = $parent_names;
|
|
$field_names[] = $field['name'];
|
|
$field['cf-names'] = $field_names;
|
|
if ( array_key_exists( 'sub_fields', $field ) ) {
|
|
$field['sub_fields'] = $this->build_fields_names( $field['sub_fields'], $field_names );
|
|
}
|
|
}
|
|
|
|
return $fields;
|
|
}
|
|
|
|
/**
|
|
* @param $search_pattern
|
|
*/
|
|
private function collect_meta_keys_to_update( $search_pattern ) {
|
|
$this->search_patterns[] = $search_pattern;
|
|
}
|
|
|
|
private function get_wildcards_field_name( array $field = array() ) {
|
|
$cf_names = $field['cf-names'];
|
|
$result = array_shift( $cf_names );
|
|
|
|
$result = esc_sql( $result );
|
|
|
|
foreach ( $cf_names as $cf_name ) {
|
|
$result .= '_' . $this->get_wildcards() . '_' . esc_sql( $cf_name );
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
private function is_a_container( $field ) {
|
|
return array_key_exists( 'sub_fields', $field ) && is_array( $field['sub_fields'] ) && count( $field['sub_fields'] );
|
|
}
|
|
|
|
private function set_field_to_be_copied( $field ) {
|
|
$custom_fields_readonly_config = $this->sitepress->get_setting( 'custom_fields_readonly_config' );
|
|
$custom_fields_readonly_config[] = $field;
|
|
$this->sitepress->set_setting( 'custom_fields_readonly_config', $custom_fields_readonly_config, true );
|
|
|
|
$custom_fields_translation = $this->sitepress->get_setting( 'custom_fields_translation' );
|
|
$custom_fields_translation[ $field ] = WPML_COPY_CUSTOM_FIELD;
|
|
$this->sitepress->set_setting( 'custom_fields_translation', $custom_fields_translation, true );
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
private function get_wildcards() {
|
|
return '%';
|
|
}
|
|
|
|
public function update_acf_field_group() {
|
|
if ( $this->is_updating_acf_group() ) {
|
|
$cache = new WPML_WP_Cache( $this->cache_group );
|
|
$cache->flush_group_cache();
|
|
|
|
$this->search_patterns = array();
|
|
$group_id = $_POST['post_ID'];
|
|
$groups = $this->get_acf_groups();
|
|
|
|
/** @var WP_Post $group */
|
|
foreach ( $groups as $group ) {
|
|
if ( (int) $group_id === $group->ID ) {
|
|
$fields = acf_get_fields( $group->ID );
|
|
if ( is_array( $fields ) && $fields ) {
|
|
$this->update_custom_fields_settings( $fields );
|
|
}
|
|
}
|
|
}
|
|
|
|
$this->update_post_meta_settings();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @return bool
|
|
*/
|
|
private function is_updating_acf_group() {
|
|
return array_key_exists( 'post_type', $_POST ) && array_key_exists( 'post_ID', $_POST ) && 'acf-field-group' === $_POST['post_type'];
|
|
}
|
|
|
|
/**
|
|
* @todo Improve this query since only ID is used no need for all fields.
|
|
*
|
|
* @return array
|
|
*/
|
|
private function get_acf_groups() {
|
|
$found = false;
|
|
$cache = new WPML_WP_Cache( $this->cache_group );
|
|
$result = $cache->get( $this->cache_key_for_fields_groups, $found );
|
|
if ( ! $found ) {
|
|
$result = get_posts( array(
|
|
'post_type' => 'acf-field-group',
|
|
'posts_per_page' => -1,
|
|
'orderby' => 'menu_order title',
|
|
'order' => 'asc',
|
|
'suppress_filters' => false, // allow WPML to modify the query
|
|
'post_status' => array( 'publish', 'acf-disabled' ),
|
|
'update_post_meta_cache' => false,
|
|
) );
|
|
$cache->set( $this->cache_key_for_fields_groups, $result );
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
}
|