Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should be able to migrate data #60

Open
simplenotezy opened this issue Sep 29, 2020 · 2 comments
Open

Should be able to migrate data #60

simplenotezy opened this issue Sep 29, 2020 · 2 comments

Comments

@simplenotezy
Copy link

What was expected

My old options page should be added upon plugin activation to the new options page. It's possible to fetch them like so:

get_options('name', 'options'); // for the default language
get_options('name_da', 'options'); // for the translated language

We have some quite huge options pages, so would be sweet if this was supported.

What happened instead

Options page is empty. I have to migrate all data manually.

@simplenotezy
Copy link
Author

I wrote a little WP CLI command that could easily optionally be run on plugin activation. This should migrate data. I have tested on our application and it works. Thought I'd share here for anybody in need of the same, or perhaps it could be integrated in the repo.

/**
 * Sync ACF Options from WPML / other multi lang plugin (where options is stored in wp_options table as options_{language_if_not_default}_{field_name})
 * This will only COPY new data and not replace existing data, so it should be safe to run.
 * 
 * The idea here is that previously a field with name 'example' would be stored in wp_options as "options_en_example" for the translated language
 * and as "options_example" for the default language. In the new polylang acf options plugin, it is stored as: "options_en_US_example" and "options_da_DK_example" (if the
 * default language would be danish)
 * 
 * This script will search for all "options_da" or "options_" and create new options with same data to "optiosn_da_DK" and "options_en_US" given the
 * two languages is da_DK and en_US
 * 
 * Usage: `wp sync-acf-options-to-polylang`
 * 
 * @author Mattias Siø Fjellvang https://constantsolutions.dk
 */

	function sync_acf_options_to_polylang($args, $assoc_args) {
		global $wpdb;

		$default_lang = false;

		$languages = get_option('_transient_pll_languages_list');
		$polylang = get_option('polylang');
		$verbose = false;

		if (isset($assoc_args['verbose']) && $assoc_args['verbose']) {
			$verbose = true;

			WP_CLI::log( 'Verbose mode enabled' );
		} else {
			WP_CLI::confirm( 'Are you sure you wish to create migrate data to Polylang ACF? No keys will be deleted' );
		}

		if(isset($polylang['default_lang']) && $polylang['default_lang']) {
			$default_lang_slug = $polylang['default_lang'];
		}
		
		foreach ($languages as $lang) {
			if ($lang['slug'] == $default_lang_slug) {
				$default_lang = $lang;
				break;
			}
		}

		if (!$default_lang) {
			WP_CLI::error('No default lang found');
		}

		$locales = array_column($languages, 'locale'); // the illegal works it cannot contain (e.g. any existing da_DK)
		$not_like = '';

		foreach ($locales as $locale) {
			$not_like .= ' AND option_name NOT LIKE "%options_' . $locale . '_%"';
		}
	
		$query = "
			SELECT
				*
			FROM
				" . $wpdb->prefix . "options
			WHERE
				(option_name LIKE '_options_%' OR option_name LIKE 'options_%')" . $not_like . "
		";

		$acf_options = $wpdb->get_results($query);

		if(!$acf_options) {
			WP_CLI::error('Could not find any ACF options');
		}

		$new_options = [];
		foreach ($acf_options as $acf_option) {
			$option_name = $acf_option->option_name;
			$lang = false;

			foreach ($languages as $language) {
				if ($language['slug'] !== $default_lang_slug && strpos($option_name, '_' . $language['slug'] . '_')) {
					// contains e.g. _da_
					$lang = $language;
					break;
				}
			}

			if ($lang) {
				$option_name = str_replace('options_' . $lang['slug'], 'options_' . $lang['locale'], $option_name);
			} else {
				// no language slug was found, must be default language that does not contain slug
				$option_name = str_replace('options_', 'options_' . $default_lang['locale'] . '_', $option_name);
			}
			
			$value = get_option($acf_option->option_name);

			$new_options[$option_name] = [
				'old_name' => $acf_option->option_name,
				'new_name' => $option_name,
				'status' => (!$value) ? 'Skip (no value)' : 'OK',
				'value' => $value
			];
		}

		if (!$verbose) {
			$progress = \WP_CLI\Utils\make_progress_bar( 'Creating new options keys compatible with Polylang ACF', count($new_options) );

			foreach ($new_options as $option) {
				$success = false;
				$action = 'insert';

				if(!get_option($option['new_name'], $option['value'])) {
					$success = add_option($option['new_name'], $option['value']);
				} else if ($option['value']) {
					$action = 'update';
					$success = update_option($option['new_name'], $option['value']);
				}

				if (!$success && $option['value']) {
					WP_CLI::log('Failed to ' . $action . ' ' . $option['new_name'] . ' representing old ' . $option['old_name']);
				}

				$progress->tick();
			}

			$progress->finish();
		} else {
			WP_CLI\Utils\format_items( 'table', $new_options, array( 'old_name', 'new_name', 'status' ) );
		}
	}

	if ( defined( 'WP_CLI' ) && WP_CLI ) {
		WP_CLI::add_command( 'sync-acf-options-to-polylang', 'sync_acf_options_to_polylang' );
	}

@Rahe
Copy link
Member

Rahe commented Jan 26, 2021

Hello,

This is to pmigratie from wpml to polylang ?
If so, I think this wp-cli command should be on a separate package too :)

Nicolas,

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants