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; } }