fieldSettings = $fieldSettings;
}
public function init_hooks() {
add_action( 'init', [ $this, 'runMigration' ] );
add_action( 'plugins_loaded', [ $this, 'showProgressInfo' ] );
}
/**
* Check if migration should run and run it.
*
* After migration it updates wp_option to indicate where it finished or if all field groups has been migrated, sets value 'done'.
*/
public function runMigration() {
if ( $this->migrationShouldRun() ) {
$offset = $this->getOffset();
if ( $this->migrate( $offset ) ) {
\update_option( self::OPTION_KEY, $offset + self::CHUNK_SIZE );
} else {
\update_option( self::OPTION_KEY, self::MIGRATED_VALUE );
}
}
}
/**
* Displays admin notification informing migration is performed in the background.
*
* @uses \ACFML\MigrateBlockPreferences::blocksBeingUpdated
*/
public function showProgressInfo() {
if ( $this->migrationShouldRun() ) {
add_action( 'admin_notices', array( $this, 'blocksBeingUpdated' ) );
}
}
/**
* HTML of the admin notice.
*
* @see \ACFML\MigrateBlockPreferences::showProgressInfo
*/
public function blocksBeingUpdated() {
?>
getOnlyBlockLocatedGroups( (array) $this->getAllFieldGroups( $offset ) );
if ( count( $fieldGroups ) > 0 ) {
foreach ( $fieldGroups as $group ) {
$this->migrateChildren( $group->ID );
}
return true;
} else {
return false;
}
}
/**
* Migrate children of given post.
*
* @param int $parentId Parent post ID
*/
private function migrateChildren( $parentId ) {
foreach ( $this->getFieldsOfGroup( $parentId ) as $field ) {
$fieldObject = acf_get_field( $field->post_name );
if ( $this->fieldSettings->fieldPreferencesNotMigrated( $fieldObject ) ) {
if ( $this->fieldSettings->field_should_be_set_to_copy_once( $fieldObject ) ) {
$this->setFieldTranslationPreference( $fieldObject, WPML_COPY_CUSTOM_FIELD );
$this->migrateChildren( $fieldObject['ID'] );
} else {
$this->setFieldTranslationPreference( $fieldObject, WPML_TRANSLATE_CUSTOM_FIELD );
}
}
}
}
/**
* Updates field translation preference in WPML settings.
*
* @param array $fieldObject ACF field in format returned by @see \acf_get_field.
* @param int $preference Preference bit to set.
*/
private function setFieldTranslationPreference( $fieldObject, $preference ) {
$fieldObject['wpml_cf_preferences'] = $preference;
$this->fieldSettings->update_field_settings( $fieldObject );
$this->fieldSettings->update_field_group_post( $fieldObject['ID'], $preference );
}
/**
* Gets field group posts from wp_posts.
*
* @param int $offset Offset where to start query for field group posts.
*
* @return int[]|\WP_Post[]
*/
private function getAllFieldGroups( $offset ) {
return get_posts( [
'numberposts' => self::CHUNK_SIZE,
'offset' => $offset,
'post_type' => 'acf-field-group'
] );
}
/**
* Filters field group to return only those which has set location rule to be used in Gutenberg Blocks.
*
* @param \WP_Post[] $fieldGroups
*
* @return \WP_Post[]
*/
private function getOnlyBlockLocatedGroups( array $fieldGroups ) {
$blockLocatedGroups = [];
foreach ( $fieldGroups as $fieldGroup ) {
if ( isset( $fieldGroup->post_content ) ) {
if ( $this->hasBlockInDisplayRules( maybe_unserialize( $fieldGroup->post_content ) ) ) {
$blockLocatedGroups[] = $fieldGroup;
}
}
}
return $blockLocatedGroups;
}
/**
* Gets fields from wp_posts being child of given field group.
*
* @param int $parentId The ID of the parent field group.
*
* @return int[]|\WP_Post[]
*/
private function getFieldsOfGroup( $parentId ) {
return get_posts( [
'numberposts' => -1,
'post_type' => 'acf-field',
'post_parent' => $parentId
] );
}
/**
* Checks in wp_options if migration is not done yet.
*
* @return bool
*/
private function migrationShouldRun() {
return self::MIGRATED_VALUE !== \get_option( self::OPTION_KEY );
}
/**
* Returns offset (used in @return int
* @see \ACFML\MigrateBlockPreferences::migrate ) stored in wp_options between migration chunks.
*
*/
private function getOffset() {
return (int) \get_option( self::OPTION_KEY );
}
/**
* Checks if field group has display rule param.
*
* @param mixed $fieldGroup Field group.
*
* @return bool
*/
private function hasBlockInDisplayRules( $fieldGroup ) {
if ( isset( $fieldGroup['location'] ) && is_array( $fieldGroup['location'] ) ) {
foreach ( $fieldGroup['location'] as $group ) {
if ( empty( $group ) || ! is_array( $group ) ) {
continue;
}
foreach ( $group as $rule ) {
if ( isset( $rule['param'] ) && $rule['param'] === 'block' ) {
return true;
}
}
}
}
return false;
}
}