From 350737f67c0d2cee80f5b80a949324b8b43a5bef Mon Sep 17 00:00:00 2001 From: David Stone Date: Mon, 22 Dec 2025 14:50:02 -0700 Subject: [PATCH] Add Template Library and move Site Exporter to core MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Template Library Feature - Add new Template Library admin page for browsing and installing templates - Add template categories (Business, Portfolio, Blog, E-commerce, Agency, SaaS, Community) - Add API client for fetching templates from ultimatemultisite.com - Add template installer with OAuth authentication support - Add template repository with caching - Add upload template feature for importing custom templates from ZIP files - Add JavaScript UI for template browsing with search and filtering ## Site Exporter in Core - Move Site Exporter addon functionality into core plugin - Add namespace WP_Ultimo\Site_Exporter for all exporter classes - Add database classes (Manager, Import, Replace, Max_Execution_Time) - Add MU-Migration library for export/import operations - Add exporter and importer function files with backward-compatible aliases - Add auto-deactivation of Site Exporter addon when core is updated ## WordPress Sites Integration - Add export action link to each site row in wp-admin/network/sites.php - Add bulk export action for multiple sites - Add Export & Import submenu page under Sites menu - Works without requiring Ultimate Multisite setup wizard completion ## Ultimate Multisite Integration - Add Export Site and Import Site action links to Sites list page - Add Site Export widget to Site edit page with previous exports list - Add extensibility hooks for action links and widgets ## Code Quality - Enforce 'ultimate-multisite' text domain via PHPCS - Update all translation calls from 'wp-ultimo' to 'ultimate-multisite' - Add phpcs:disable for ported third-party database classes - Exclude mu-migration from PHPStan checks - Fix all security escaping issues in new files đŸ¤– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .phpcs.xml.dist | 3 +- assets/js/template-library.js | 184 ++ composer.json | 1 + composer.lock | 128 +- inc/admin-pages/class-base-admin-page.php | 2 +- .../class-site-edit-admin-page.php | 9 + .../class-site-list-admin-page.php | 12 +- .../class-template-library-admin-page.php | 673 +++++++ inc/admin/class-network-usage-columns.php | 4 +- inc/checkout/composer.json | 14 + inc/class-wp-ultimo.php | 108 ++ inc/compat/class-multiple-accounts-compat.php | 4 + inc/debug/class-debug.php | 2 +- inc/development/class-toolkit.php | 2 +- inc/functions/exporter.php | 447 +++++ inc/functions/importer.php | 300 +++ inc/helpers/class-hash.php | 4 +- .../class-unique-customer-email.php | 86 + inc/models/class-membership.php | 2 +- inc/site-exporter/class-site-exporter.php | 1625 +++++++++++++++++ inc/site-exporter/database/class-import.php | 235 +++ inc/site-exporter/database/class-manager.php | 200 ++ .../database/class-max-execution-time.php | 62 + inc/site-exporter/database/class-replace.php | 431 +++++ inc/site-exporter/mu-migration/LICENSE.txt | 9 + inc/site-exporter/mu-migration/README.md | 125 ++ .../mu-migration/bin/install-package-tests.sh | 10 + inc/site-exporter/mu-migration/bin/test.sh | 14 + inc/site-exporter/mu-migration/composer.json | 25 + inc/site-exporter/mu-migration/composer.lock | 1150 ++++++++++++ .../features/01-load-wp-cli.feature | 10 + .../mu-migration/features/02-info.feature | 12 + .../mu-migration/features/03-export.feature | 341 ++++ .../mu-migration/features/04-import.feature | 189 ++ .../mu-migration/features/05-posts.feature | 37 + .../features/06-migration.feature | 126 ++ .../features/bootstrap/FeatureContext.php | 946 ++++++++++ .../features/bootstrap/Process.php | 118 ++ .../features/bootstrap/ProcessRun.php | 67 + .../features/bootstrap/support.php | 218 +++ .../mu-migration/features/bootstrap/utils.php | 1111 +++++++++++ .../features/data/images/beach.jpg | Bin 0 -> 227604 bytes .../features/data/images/mossoro.jpg | Bin 0 -> 155842 bytes .../features/data/images/wp_chara.jpg | Bin 0 -> 95622 bytes .../mu-migration/features/extra/no-mail.php | 6 + .../mu-migration/features/steps/given.php | 292 +++ .../mu-migration/features/steps/then.php | 260 +++ .../mu-migration/features/steps/when.php | 58 + .../features/tests/csv_matches_user.php | 75 + .../commands/class-mu-migration-base.php | 202 ++ .../commands/class-mu-migration-export.php | 532 ++++++ .../commands/class-mu-migration-import.php | 738 ++++++++ .../commands/class-mu-migration-posts.php | 179 ++ .../commands/class-mu-migration-users.php | 159 ++ .../includes/commands/class-mu-migration.php | 26 + .../mu-migration/includes/helpers.php | 459 +++++ .../mu-migration/mu-migration.php | 40 + .../mu-migration/utils/behat-tags.php | 75 + inc/sso/class-admin-bar-magic-links.php | 12 +- inc/tax/class-dashboard-taxes-tab.php | 2 +- inc/template-library/class-api-client.php | 214 +++ .../class-template-installer.php | 245 +++ .../class-template-library.php | 142 ++ .../class-template-repository.php | 317 ++++ phpstan.neon.dist | 2 + tests/WP_Ultimo/Helpers/Hash_Test.php | 2 +- .../Helpers/Unique_Customer_Email_Test.php | 146 ++ views/template-library/details.php | 216 +++ views/template-library/template-library.php | 284 +++ views/wizards/host-integrations/ready.php | 2 +- 70 files changed, 13648 insertions(+), 83 deletions(-) create mode 100644 assets/js/template-library.js create mode 100644 inc/admin-pages/class-template-library-admin-page.php create mode 100644 inc/checkout/composer.json create mode 100644 inc/functions/exporter.php create mode 100644 inc/functions/importer.php create mode 100644 inc/helpers/validation-rules/class-unique-customer-email.php create mode 100644 inc/site-exporter/class-site-exporter.php create mode 100644 inc/site-exporter/database/class-import.php create mode 100644 inc/site-exporter/database/class-manager.php create mode 100644 inc/site-exporter/database/class-max-execution-time.php create mode 100644 inc/site-exporter/database/class-replace.php create mode 100644 inc/site-exporter/mu-migration/LICENSE.txt create mode 100644 inc/site-exporter/mu-migration/README.md create mode 100644 inc/site-exporter/mu-migration/bin/install-package-tests.sh create mode 100644 inc/site-exporter/mu-migration/bin/test.sh create mode 100644 inc/site-exporter/mu-migration/composer.json create mode 100644 inc/site-exporter/mu-migration/composer.lock create mode 100644 inc/site-exporter/mu-migration/features/01-load-wp-cli.feature create mode 100644 inc/site-exporter/mu-migration/features/02-info.feature create mode 100644 inc/site-exporter/mu-migration/features/03-export.feature create mode 100644 inc/site-exporter/mu-migration/features/04-import.feature create mode 100644 inc/site-exporter/mu-migration/features/05-posts.feature create mode 100644 inc/site-exporter/mu-migration/features/06-migration.feature create mode 100644 inc/site-exporter/mu-migration/features/bootstrap/FeatureContext.php create mode 100644 inc/site-exporter/mu-migration/features/bootstrap/Process.php create mode 100644 inc/site-exporter/mu-migration/features/bootstrap/ProcessRun.php create mode 100644 inc/site-exporter/mu-migration/features/bootstrap/support.php create mode 100644 inc/site-exporter/mu-migration/features/bootstrap/utils.php create mode 100644 inc/site-exporter/mu-migration/features/data/images/beach.jpg create mode 100644 inc/site-exporter/mu-migration/features/data/images/mossoro.jpg create mode 100644 inc/site-exporter/mu-migration/features/data/images/wp_chara.jpg create mode 100644 inc/site-exporter/mu-migration/features/extra/no-mail.php create mode 100644 inc/site-exporter/mu-migration/features/steps/given.php create mode 100644 inc/site-exporter/mu-migration/features/steps/then.php create mode 100644 inc/site-exporter/mu-migration/features/steps/when.php create mode 100644 inc/site-exporter/mu-migration/features/tests/csv_matches_user.php create mode 100644 inc/site-exporter/mu-migration/includes/commands/class-mu-migration-base.php create mode 100644 inc/site-exporter/mu-migration/includes/commands/class-mu-migration-export.php create mode 100644 inc/site-exporter/mu-migration/includes/commands/class-mu-migration-import.php create mode 100644 inc/site-exporter/mu-migration/includes/commands/class-mu-migration-posts.php create mode 100644 inc/site-exporter/mu-migration/includes/commands/class-mu-migration-users.php create mode 100644 inc/site-exporter/mu-migration/includes/commands/class-mu-migration.php create mode 100644 inc/site-exporter/mu-migration/includes/helpers.php create mode 100644 inc/site-exporter/mu-migration/mu-migration.php create mode 100644 inc/site-exporter/mu-migration/utils/behat-tags.php create mode 100644 inc/template-library/class-api-client.php create mode 100644 inc/template-library/class-template-installer.php create mode 100644 inc/template-library/class-template-library.php create mode 100644 inc/template-library/class-template-repository.php create mode 100644 tests/WP_Ultimo/Helpers/Unique_Customer_Email_Test.php create mode 100644 views/template-library/details.php create mode 100644 views/template-library/template-library.php diff --git a/.phpcs.xml.dist b/.phpcs.xml.dist index 22b0ace2..ba442ece 100644 --- a/.phpcs.xml.dist +++ b/.phpcs.xml.dist @@ -8,6 +8,7 @@ /node_modules/ /dependencies/ /../wordpress/ + /inc/site-exporter/mu-migration/ @@ -111,7 +112,7 @@ - + diff --git a/assets/js/template-library.js b/assets/js/template-library.js new file mode 100644 index 00000000..e256b7b3 --- /dev/null +++ b/assets/js/template-library.js @@ -0,0 +1,184 @@ +/* global Vue, wu_template_library, ajaxurl, _ */ +(function($) { + + const search_template = new Vue({ + el: '#search-templates', + data: { + search: wu_template_library.search, + }, + }); + + const wu_main_template_app = new Vue({ + el: '#wu-template-library', + data() { + + return { + loading: true, + category: wu_template_library.category, + templates: [], + }; + + }, + mounted() { + + this.fetch_templates_list(); + + }, + computed: { + search() { + + return search_template.search; + + }, + i18n() { + + return window.wu_template_library.i18n; + + }, + categories() { + + let categories = []; + + _.each(this.templates, function(template) { + + if (template.categories && Array.isArray(template.categories)) { + categories = categories.concat(template.categories); + } + + }); + + return _.unique(categories, function(cat) { + return cat.slug; + }); + + }, + templates_list() { + + const app = this; + + return _.filter(app.templates, function(template) { + + // Filter by category + if (app.category !== 'all') { + const hasCategory = template.categories && template.categories.some(cat => cat.slug === app.category); + if (!hasCategory) { + return false; + } + } + + // Filter by search + if (!app.search) { + + return true; + + } + + const search_fields = [ + template.slug || '', + template.name || '', + template.description || '', + template.short_description || '', + template.author || '', + template.industry_type || '', + ]; + + // Add category names to search + if (template.categories && Array.isArray(template.categories)) { + template.categories.forEach(function(cat) { + search_fields.push(cat.name || cat.slug || ''); + }); + } + + return search_fields.join(' ').toLowerCase().indexOf(app.search.toLowerCase()) > -1; + + }); + + }, + count() { + + return this.templates_list.length; + + }, + }, + methods: { + fetch_templates_list() { + + const app = this; + + $.ajax({ + method: 'GET', + url: ajaxurl, + data: { + action: 'serve_templates_list', + }, + success(data) { + + if (data.success && data.data) { + app.templates = data.data; + } else { + app.templates = []; + } + + app.loading = false; + + }, + error() { + + app.templates = []; + app.loading = false; + + }, + }); + + }, + }, + }); + + new Vue({ + el: '.wp-heading-inline', + data: {}, + computed: { + count() { + + return wu_main_template_app.count; + + }, + }, + }); + + new Vue({ + el: '#templates-menu', + data: {}, + methods: { + set_category(category) { + + this.main_app.category = category; + + const url = new URL(window.location.href); + + url.searchParams.set('tab', category); + + history.pushState({}, null, url); + + }, + }, + computed: { + main_app() { + + return wu_main_template_app; + + }, + category() { + + return wu_main_template_app.category; + + }, + available_categories() { + + return wu_main_template_app.categories; + + }, + }, + }); + +}(jQuery)); diff --git a/composer.json b/composer.json index 63e7cd7a..d06348cf 100644 --- a/composer.json +++ b/composer.json @@ -56,6 +56,7 @@ "jasny/sso": "^0.4.2", "nyholm/psr7": "^1.8.0", "symfony/cache": "^5.4.29", + "symfony/finder": "^5.4", "scssphp/scssphp": "^1.11.1", "cweagans/composer-patches": "^1.7", "woocommerce/action-scheduler": "^3.9.1", diff --git a/composer.lock b/composer.lock index 3c13b255..711f5b4a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "cb2d45765e1edc0ba8eb9510154108dd", + "content-hash": "31f00de0de1918010b3e5e53ded6879b", "packages": [ { "name": "amphp/amp", @@ -3979,6 +3979,69 @@ ], "time": "2024-09-25T14:11:13+00:00" }, + { + "name": "symfony/finder", + "version": "v5.4.45", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "63741784cd7b9967975eec610b256eed3ede022b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/63741784cd7b9967975eec610b256eed3ede022b", + "reference": "63741784cd7b9967975eec610b256eed3ede022b", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php80": "^1.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v5.4.45" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-28T13:32:08+00:00" + }, { "name": "symfony/polyfill-php73", "version": "v1.33.0", @@ -9118,69 +9181,6 @@ ], "time": "2024-10-22T13:05:35+00:00" }, - { - "name": "symfony/finder", - "version": "v5.4.45", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "63741784cd7b9967975eec610b256eed3ede022b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/63741784cd7b9967975eec610b256eed3ede022b", - "reference": "63741784cd7b9967975eec610b256eed3ede022b", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-php80": "^1.16" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Finds files and directories via an intuitive fluent interface", - "homepage": "https://symfony.com", - "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.45" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-09-28T13:32:08+00:00" - }, { "name": "symfony/polyfill-ctype", "version": "v1.33.0", diff --git a/inc/admin-pages/class-base-admin-page.php b/inc/admin-pages/class-base-admin-page.php index bdc068e6..d5f9aa80 100644 --- a/inc/admin-pages/class-base-admin-page.php +++ b/inc/admin-pages/class-base-admin-page.php @@ -176,7 +176,7 @@ public function __construct() { __FUNCTION__, sprintf( /* translators: 1: The current class. 2: 'init'. */ - esc_html__('Admin page %1$s loaded too early. Admin page should be loaded at the %2$s action or later.'), + esc_html__('Admin page %1$s loaded too early. Admin page should be loaded at the %2$s action or later.', 'ultimate-multisite'), '' . static::class . '', 'init' ), diff --git a/inc/admin-pages/class-site-edit-admin-page.php b/inc/admin-pages/class-site-edit-admin-page.php index fae2697c..0873038d 100644 --- a/inc/admin-pages/class-site-edit-admin-page.php +++ b/inc/admin-pages/class-site-edit-admin-page.php @@ -299,6 +299,15 @@ public function register_widgets(): void { parent::register_widgets(); + /** + * Allows other components to register widgets on the Site edit page. + * + * @since 2.5.0 + * + * @param Site_Edit_Admin_Page $page The current admin page instance. + */ + do_action('wu_edit_site_page_register_widgets', $this); + $label = $this->get_object()->get_type_label(); $class = $this->get_object()->get_type_class(); diff --git a/inc/admin-pages/class-site-list-admin-page.php b/inc/admin-pages/class-site-list-admin-page.php index 2eb7d60a..bfd72460 100644 --- a/inc/admin-pages/class-site-list-admin-page.php +++ b/inc/admin-pages/class-site-list-admin-page.php @@ -547,7 +547,7 @@ public function get_submenu_title() { */ public function action_links() { - return [ + $links = [ [ 'label' => __('Add Site', 'ultimate-multisite'), 'icon' => 'wu-circle-with-plus', @@ -555,6 +555,16 @@ public function action_links() { 'url' => wu_get_form_url('add_new_site'), ], ]; + + /** + * Filters the action links for the Sites list page. + * + * @since 2.5.0 + * + * @param array $links The action links. + * @return array + */ + return apply_filters('wu_site_list_page_action_links', $links); } /** diff --git a/inc/admin-pages/class-template-library-admin-page.php b/inc/admin-pages/class-template-library-admin-page.php new file mode 100644 index 00000000..5a1cd6df --- /dev/null +++ b/inc/admin-pages/class-template-library-admin-page.php @@ -0,0 +1,673 @@ + 'wu_read_settings', + ]; + + /** + * Should we hide admin notices on this page? + * + * @since 2.5.0 + * @var bool + */ + protected $hide_admin_notices = false; + + /** + * Should we force the admin menu into a folded state? + * + * @since 2.5.0 + * @var bool + */ + protected $fold_menu = false; + + /** + * Holds the section slug for the URLs. + * + * @since 2.5.0 + * @var string + */ + protected $section_slug = 'tab'; + + /** + * Defines if the step links on the side are clickable or not. + * + * @since 2.5.0 + * @var bool + */ + protected $clickable_navigation = true; + + /** + * Template Repository instance. + * + * @since 2.5.0 + * @var Template_Repository|null + */ + protected ?Template_Repository $repository = null; + + /** + * Allow child classes to add hooks to be run once the page is loaded. + * + * @since 2.5.0 + * @return void + */ + public function init(): void { + + parent::init(); + + add_action('wp_ajax_serve_templates_list', [$this, 'serve_templates_list']); + } + + /** + * Register forms. + * + * @since 2.5.0 + * @return void + */ + public function register_forms(): void { + + wu_register_form( + 'template_more_info', + [ + 'render' => [$this, 'display_more_info'], + 'handler' => [$this, 'install_template'], + ] + ); + + wu_register_form( + 'upload_template', + [ + 'render' => [$this, 'render_upload_template_modal'], + 'handler' => [$this, 'handle_upload_template_modal'], + 'capability' => 'manage_network', + ] + ); + } + + /** + * Renders the upload template modal. + * + * @since 2.5.0 + * @return void + */ + public function render_upload_template_modal(): void { + + // Reset upload limits for large ZIP files + \WP_Ultimo\Site_Exporter\Site_Exporter::get_instance()->reset_upload_limits(); + + $fields = [ + 'template_name' => [ + 'type' => 'text', + 'title' => __('Template Name', 'ultimate-multisite'), + 'placeholder' => __('My Awesome Template', 'ultimate-multisite'), + 'desc' => __('A descriptive name for this template.', 'ultimate-multisite'), + ], + 'zip_file' => [ + 'type' => 'text', + 'title' => __('ZIP File URL', 'ultimate-multisite'), + 'placeholder' => __('https://example.com/export.zip', 'ultimate-multisite'), + 'desc' => __('Upload or enter URL to a site export ZIP file.', 'ultimate-multisite'), + 'html_attr' => [ + 'id' => 'wu-template-zip-url', + ], + ], + 'upload_btn' => [ + 'type' => 'html', + 'content' => sprintf( + '', + __('Upload ZIP File', 'ultimate-multisite') + ), + 'wrapper_classes' => 'wu-mb-4', + ], + 'template_url' => [ + 'type' => 'text', + 'title' => __('Template Site URL', 'ultimate-multisite'), + 'placeholder' => is_subdomain_install() ? 'template-name.example.com' : 'example.com/template-name', + 'desc' => __('The URL for the new template site.', 'ultimate-multisite'), + ], + 'categories' => [ + 'type' => 'text', + 'title' => __('Categories', 'ultimate-multisite'), + 'placeholder' => __('business, portfolio', 'ultimate-multisite'), + 'desc' => __('Comma-separated list of categories.', 'ultimate-multisite'), + ], + 'submit_button' => [ + 'type' => 'submit', + 'title' => __('Create Template', 'ultimate-multisite'), + 'value' => 'save', + 'classes' => 'button button-primary wu-w-full', + 'wrapper_classes' => 'wu-items-end wu-text-right', + ], + ]; + + $form = new \WP_Ultimo\UI\Form( + 'upload_template', + $fields, + [ + 'views' => 'admin-pages/fields', + 'classes' => 'wu-modal-form wu-widget-list wu-striped wu-m-0 wu-mt-0', + 'field_wrapper_classes' => 'wu-w-full wu-box-border wu-items-center wu-flex wu-justify-between wu-p-4 wu-m-0 wu-border-t wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300 wu-border-solid', + ] + ); + + $form->render(); + + // Add media uploader script + ?> + + $template_url, + 'new_url' => $template_url, + 'delete_file' => false, + 'zip_url' => $zip_url, + ] + ); + + if (is_wp_error($result)) { + wp_send_json_error($result); + } + + // Parse categories + $category_list = array_map('trim', explode(',', $categories)); + $category_list = array_filter($category_list); + + // Note: The site will be created by the import process. + // We set a transient to update it to site_template type after import completes. + set_site_transient( + 'wu_pending_template_setup_' . md5($template_url), + [ + 'name' => $template_name, + 'url' => $template_url, + 'categories' => $category_list, + ], + HOUR_IN_SECONDS + ); + + wp_send_json_success( + [ + 'redirect_url' => wu_network_admin_url( + 'wp-ultimo-sites', + [ + 'type' => 'site_template', + 'updated' => __('Template import started. The site will be available shortly.', 'ultimate-multisite'), + ] + ), + ] + ); + } + + /** + * Gets the Template Repository. + * + * @since 2.5.0 + * @return Template_Repository + */ + protected function get_repository(): Template_Repository { + + if (null === $this->repository) { + $this->repository = new Template_Repository(); + } + + return $this->repository; + } + + /** + * Get a template given a slug. + * + * @since 2.5.0 + * @param string $template_slug The template slug. + * @return array|null + */ + private function get_template(string $template_slug): ?array { + + $templates = $this->get_templates_list(); + + foreach ($templates as $template) { + if ($template['slug'] === $template_slug) { + return $template; + } + } + + return null; + } + + /** + * Displays the more info modal. + * + * @since 2.5.0 + * @return void + */ + public function display_more_info(): void { + + $template_slug = wu_request('template'); + + $template = $this->get_template($template_slug); + + wu_get_template( + 'template-library/details', + [ + 'template' => (object) $template, + 'template_slug' => $template_slug, + ] + ); + + do_action('wu_form_scripts', false); + } + + /** + * Installs a given template. + * + * @since 2.5.0 + * @return void + */ + public function install_template(): void { + + if (! current_user_can('manage_network_plugins')) { + $error = new \WP_Error('error', __('You do not have enough permissions to perform this task.', 'ultimate-multisite')); + + wp_send_json_error($error); + } + + $template_slug = wu_request('template'); + + $template = $this->get_template($template_slug); + + if (! $template) { + wp_send_json_error(new \WP_Error('not_found', __('Template not found.', 'ultimate-multisite'))); + } + + $download_url = $template['download_url'] ?? ''; + + if (! $download_url) { + wp_send_json_error( + new \WP_Error( + 'no_download', + sprintf( + /* translators: %s slug of the template. */ + __('Unable to download template. User does not have permission to install %s', 'ultimate-multisite'), + $template_slug + ) + ) + ); + } + + // Security check: Ensure URL is from our domain + $allowed = strncmp($download_url, MULTISITE_ULTIMATE_UPDATE_URL, strlen(MULTISITE_ULTIMATE_UPDATE_URL)) === 0; + + if (! $allowed) { + $error = new \WP_Error('insecure-url', __('You are trying to download a template from an insecure URL', 'ultimate-multisite')); + wp_send_json_error($error); + } + + // Install the template + $installer = $this->get_repository()->get_installer(); + + $result = $installer->install( + $download_url, + [ + 'slug' => $template['slug'], + 'name' => $template['name'], + 'version' => $template['template_version'], + ] + ); + + if (is_wp_error($result)) { + wp_send_json_error($result); + } + + // Clear template cache to reflect installation + $this->get_repository()->clear_cache(); + + wp_send_json_success( + [ + 'redirect_url' => wu_network_admin_url( + 'wp-ultimo-sites', + [ + 'type' => 'site_template', + ] + ), + 'message' => __('Template installed successfully!', 'ultimate-multisite'), + ] + ); + } + + /** + * Enqueue the necessary scripts. + * + * @since 2.5.0 + * @return void + */ + public function register_scripts(): void { + + wp_enqueue_style('theme'); + + // Enqueue media uploader for template uploads + wp_enqueue_media(); + + wp_register_script('wu-template-library', wu_get_asset('template-library.js', 'js'), ['jquery', 'wu-vue', 'underscore'], wu_get_version(), true); + + wp_localize_script( + 'wu-template-library', + 'wu_template_library', + [ + 'search' => wu_request('s', ''), + 'category' => wu_request('tab', 'all'), + 'i18n' => [ + 'all' => __('All Templates', 'ultimate-multisite'), + 'loading' => __('Loading templates...', 'ultimate-multisite'), + 'no_result' => __('No templates found.', 'ultimate-multisite'), + ], + ] + ); + + wp_enqueue_script('wu-template-library'); + } + + /** + * Fetches the list of templates available. + * + * @since 2.5.0 + * @return array + */ + protected function get_templates_list(): array { + + $templates = $this->get_repository()->get_templates(); + + if (is_wp_error($templates)) { + wu_log_add( + 'api-calls', + sprintf( + /* translators: %s error message. */ + __('Failed to fetch templates from API: %s', 'ultimate-multisite'), + $templates->get_error_message() + ) + ); + return []; + } + + return $templates; + } + + /** + * Gets the list of templates from the remote server. + * + * @since 2.5.0 + * @return void + */ + public function serve_templates_list(): void { + + $templates_list = $this->get_templates_list(); + + wp_send_json_success($templates_list); + } + + /** + * Returns the title of the page. + * + * @since 2.5.0 + * @return string Title of the page. + */ + public function get_title(): string { + + return __('Template Library', 'ultimate-multisite'); + } + + /** + * Returns the title of menu for this page. + * + * @since 2.5.0 + * @return string Menu label of the page. + */ + public function get_menu_title(): string { + + return __('Template Library', 'ultimate-multisite'); + } + + /** + * Returns the title links for this page. + * + * @since 2.5.0 + * @return array + */ + public function get_title_links(): array { + + return [ + [ + 'label' => __('Upload Template', 'ultimate-multisite'), + 'icon' => 'upload', + 'classes' => 'wubox', + 'url' => wu_get_form_url('upload_template'), + ], + ]; + } + + /** + * Every child class should implement the output method to display the contents of the page. + * + * @since 2.5.0 + * @return void + */ + public function output(): void { + + $addon_repo = \WP_Ultimo::get_instance()->get_addon_repository(); + + $redirect_url = wu_network_admin_url('wp-ultimo-template-library'); + $code = wu_request('code'); + + if (wu_request('logout') && wp_verify_nonce(wu_request('_wpnonce'), 'logout')) { + $addon_repo->delete_tokens(); + } + + $more_info_url = wu_get_form_url( + 'template_more_info', + [ + 'width' => 768, + 'template' => 'TEMPLATE_SLUG', + ] + ); + + $user = $addon_repo->get_user_data(); + + if (! $user && $code) { + $addon_repo->save_access_token($code, $redirect_url); + $user = $addon_repo->get_user_data(); + } + + wu_get_template( + 'template-library/template-library', + [ + 'screen' => get_current_screen(), + 'page' => $this, + 'classes' => '', + 'sections' => $this->get_sections(), + 'current_section' => $this->get_current_section(), + 'clickable_navigation' => $this->clickable_navigation, + 'more_info_url' => $more_info_url, + 'oauth_url' => $addon_repo->get_oauth_url(), + 'logout_url' => wu_network_admin_url( + 'wp-ultimo-template-library', + [ + 'logout' => 'logout', + '_wpnonce' => wp_create_nonce('logout'), + ] + ), + 'user' => $user ?? false, + ] + ); + } + + /** + * Returns the list of settings sections. + * + * @since 2.5.0 + * @return array + */ + public function get_sections(): array { + + return [ + 'all' => [ + 'title' => __('All Templates', 'ultimate-multisite'), + 'icon' => 'dashicons-wu-grid', + ], + 'business' => [ + 'title' => __('Business', 'ultimate-multisite'), + 'icon' => 'dashicons-wu-briefcase', + ], + 'portfolio' => [ + 'title' => __('Portfolio', 'ultimate-multisite'), + 'icon' => 'dashicons-wu-image', + ], + 'blog' => [ + 'title' => __('Blog', 'ultimate-multisite'), + 'icon' => 'dashicons-wu-text-page', + ], + 'ecommerce' => [ + 'title' => __('E-commerce', 'ultimate-multisite'), + 'icon' => 'dashicons-wu-shop', + ], + 'agency' => [ + 'title' => __('Agency', 'ultimate-multisite'), + 'icon' => 'dashicons-wu-rocket', + ], + 'saas' => [ + 'title' => __('SaaS', 'ultimate-multisite'), + 'icon' => 'dashicons-wu-cloud', + ], + 'community' => [ + 'title' => __('Community', 'ultimate-multisite'), + 'icon' => 'dashicons-wu-users', + ], + ]; + } + + /** + * Default handler for step submission. Simply redirects to the next step. + * + * @since 2.5.0 + * @return void + */ + public function default_handler(): void { + // Not used for this page. + } +} diff --git a/inc/admin/class-network-usage-columns.php b/inc/admin/class-network-usage-columns.php index 840f8cc7..e71f5153 100644 --- a/inc/admin/class-network-usage-columns.php +++ b/inc/admin/class-network-usage-columns.php @@ -172,7 +172,7 @@ public function manage_themes_custom_column(string $column_name, string $theme_k if ( $theme_data->parent() ) { echo '
' . sprintf( // Translators: The placeholder will be replaced by the name of the parent theme. - esc_attr__('This is a child theme of %s.', 'multisite-enhancements'), + esc_attr__('This is a child theme of %s.', 'ultimate-multisite'), '' . esc_attr($theme_data->parent()->Name) . '' ); } @@ -182,7 +182,7 @@ public function manage_themes_custom_column(string $column_name, string $theme_k if ( count($used_as_parent) ) { echo '
' . esc_attr__( 'This is used as a parent theme by:', - 'multisite-enhancements' + 'ultimate-multisite' ) . ' '; echo esc_html(implode(', ', $used_as_parent)); } diff --git a/inc/checkout/composer.json b/inc/checkout/composer.json new file mode 100644 index 00000000..f2564799 --- /dev/null +++ b/inc/checkout/composer.json @@ -0,0 +1,14 @@ +{ + "name": "vendor_name/checkout", + "description": "description", + "minimum-stability": "stable", + "license": "proprietary", + "authors": [ + { + "name": "dave", + "email": "email@example.com" + } + ], + "require": { + } +} diff --git a/inc/class-wp-ultimo.php b/inc/class-wp-ultimo.php index 0581b97b..731d6cac 100644 --- a/inc/class-wp-ultimo.php +++ b/inc/class-wp-ultimo.php @@ -179,6 +179,12 @@ public function init(): void { */ $this->notices = WP_Ultimo\Admin_Notices::get_instance(); + /* + * Show notice if Site Exporter addon was auto-deactivated. + */ + add_action('network_admin_notices', [$this, 'show_site_exporter_deactivation_notice']); + add_action('admin_notices', [$this, 'show_site_exporter_deactivation_notice']); + /* * Loads the Ultimate Multisite scripts handler */ @@ -381,6 +387,23 @@ public function load_public_apis(): void { require_once wu_path('inc/functions/invoice.php'); require_once wu_path('inc/functions/tax.php'); + /** + * Site Exporter and Importer APIs. + * + * Functions for exporting and importing sites. + * + * Since 2.5.0, Site Exporter is part of core. We need to + * deactivate the legacy addon if it's still active to + * prevent function redeclaration conflicts. + * + * @see wu_exporter_export() + * @see wu_exporter_import() + */ + $this->maybe_deactivate_site_exporter_addon(); + + require_once wu_path('inc/functions/exporter.php'); + require_once wu_path('inc/functions/importer.php'); + /** * Access Control. * @@ -517,6 +540,11 @@ protected function load_extra_components(): void { */ \WP_Ultimo\Tax\Tax::get_instance(); + /* + * Loads the Site Exporter + */ + \WP_Ultimo\Site_Exporter\Site_Exporter::get_instance(); + /* * Loads the template placeholders */ @@ -812,6 +840,8 @@ protected function load_admin_pages(): void { new WP_Ultimo\Admin_Pages\Addons_Admin_Page(); + new WP_Ultimo\Admin_Pages\Template_Library_Admin_Page(); + do_action('wp_ultimo_admin_pages'); } @@ -984,4 +1014,82 @@ public function grant_customer_capabilities($allcaps, $caps, $args, $user) { return $allcaps; } + + /** + * Deactivates the legacy Site Exporter addon if active. + * + * Since 2.5.0, Site Exporter functionality is part of core. + * We need to deactivate the addon automatically to prevent + * function redeclaration conflicts. + * + * @since 2.5.0 + * @return void + */ + private function maybe_deactivate_site_exporter_addon(): void { + + $addon_file = 'ultimate-multisite-site-exporter/ultimate-multisite-site-exporter.php'; + + // Check if the addon is network activated + if (is_multisite()) { + $network_plugins = get_site_option('active_sitewide_plugins', []); + + if (isset($network_plugins[ $addon_file ])) { + unset($network_plugins[ $addon_file ]); + update_site_option('active_sitewide_plugins', $network_plugins); + + // Set a transient to show a notice after redirect + set_site_transient('wu_site_exporter_addon_deactivated', true, 60); + } + } + + // Check if the addon is activated on the current site + $active_plugins = get_option('active_plugins', []); + $key = array_search($addon_file, $active_plugins, true); + + if (false !== $key) { + unset($active_plugins[ $key ]); + update_option('active_plugins', array_values($active_plugins)); + + // Set a transient to show a notice after redirect + set_transient('wu_site_exporter_addon_deactivated', true, 60); + } + } + + /** + * Shows a notice when the Site Exporter addon was auto-deactivated. + * + * @since 2.5.0 + * @return void + */ + public function show_site_exporter_deactivation_notice(): void { + + $show_notice = false; + + // Check network transient first + if (is_multisite() && get_site_transient('wu_site_exporter_addon_deactivated')) { + delete_site_transient('wu_site_exporter_addon_deactivated'); + $show_notice = true; + } + + // Check regular transient + if (get_transient('wu_site_exporter_addon_deactivated')) { + delete_transient('wu_site_exporter_addon_deactivated'); + $show_notice = true; + } + + if (! $show_notice) { + return; + } + + ?> +
+

+ +

+

+ +

+
+ prepare() method here because it will * escape the %s placeholder, which will break the query. diff --git a/inc/debug/class-debug.php b/inc/debug/class-debug.php index 5d0def49..2f34a8a1 100644 --- a/inc/debug/class-debug.php +++ b/inc/debug/class-debug.php @@ -385,7 +385,7 @@ public function handle_debug_generator_form(): void { wp_send_json_success( [ - 'redirect_url' => wu_network_admin_url('wp-ultimo'), + 'redirect_url' => wu_network_admin_url('ultimate-multisite'), ] ); } diff --git a/inc/development/class-toolkit.php b/inc/development/class-toolkit.php index 50892a8e..efc04dce 100644 --- a/inc/development/class-toolkit.php +++ b/inc/development/class-toolkit.php @@ -338,7 +338,7 @@ public function register_collector_overview(array $collectors, \QueryMonitor $qm */ public function add_overview_panel($output) { - $collector = \QM_Collectors::get('wp-ultimo'); + $collector = \QM_Collectors::get('ultimate-multisite'); $output['wp-ultimo'] = new Query_Monitor\Panel\Overview($collector); diff --git a/inc/functions/exporter.php b/inc/functions/exporter.php new file mode 100644 index 00000000..addd3888 --- /dev/null +++ b/inc/functions/exporter.php @@ -0,0 +1,447 @@ + $site_id, + 'options' => $options, + 'hash' => $hash, + ], + 'site-exporter' + ); + } else { + do_action_ref_array( + 'wu_export_site', + [ + 'site_id' => $site_id, + 'options' => $options, + ], + 'site-exporter' + ); + } + + return true; +} + +/** + * Gets a list of all the exports generated to date. + * + * @since 2.5.0 + * @return array + */ +function wu_exporter_get_all_exports(): array { + + $path = wu_maybe_create_folder('wu-site-exports'); + + $exports = Finder::create() + ->files() + ->name('*.zip') + ->sortByModifiedTime() + ->reverseSorting() + ->in($path); + + $results = []; + $base_url = wu_exporter_get_folder(); + + foreach ($exports as $file) { + $results[] = [ + 'file' => $file->getFilename(), + 'path' => $file->getPathname(), + 'date' => wp_date(get_option('date_format') . ' ' . get_option('time_format'), $file->getMTime()), + 'size' => size_format($file->getSize()), + 'url' => trailingslashit($base_url) . $file->getFilename(), + ]; + } + + return $results; +} + +/** + * Gets the exporter URL for the folder. + * + * @since 2.5.0 + * @return string + */ +function wu_exporter_get_folder(): string { + + return WP_Ultimo()->helper->get_folder_url('wu-site-exports'); +} + +/** + * Gets the site object based on the export name. + * + * @since 2.5.0 + * + * @param string $export_name The file name. + * @return \WP_Ultimo\Models\Site|false + */ +function wu_exporter_get_site_from_export_name(string $export_name) { + + $matches = []; + + preg_match('/wu-site-export-([0-9]+)/', $export_name, $matches); + + $site_id = absint($matches[1] ?? 0); + + return wu_get_site($site_id); +} + +/** + * Saves the time it took to generate the zip. + * + * @since 2.5.0 + * + * @param string $file The export filename. + * @param float $time The time it took. + * @return bool + */ +function wu_exporter_save_generation_time(string $file, float $time): bool { + + $times = wu_get_option('exporter_generation_times', []); + + $times[ $file ] = $time; + + return wu_save_option('exporter_generation_times', $times); +} + +/** + * Get the generated time for a given export. + * + * @since 2.5.0 + * + * @param string $file The file name. + * @return string + */ +function wu_exporter_get_generation_time(string $file): string { + + $times = wu_get_option('exporter_generation_times', []); + + $time = wu_get_isset($times, $file, false); + + if (false === $time) { + return __('Time to generate not saved', 'ultimate-multisite'); + } + + $now = time(); + + return human_time_diff($now, $now + $time); +} + +/** + * Adds a particular site as pending. + * + * @since 2.5.0 + * + * @param int $site_id The site ID. + * @param array $options The flags on what to export. + * @param bool $async If we should generate the export file asynchronously. + * @return string + */ +function wu_exporter_add_pending(int $site_id, array $options = [], bool $async = false): string { + + $base = [$site_id, $options, $async]; + + $hash = md5(serialize($base)); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize + + wu_exporter_set_transient("wu_pending_site_export_{$hash}", $site_id, 2 * HOUR_IN_SECONDS); + + return $hash; +} + +/** + * Get pending exports. + * + * @since 2.5.0 + * @return array + */ +function wu_exporter_get_pending(): array { + + global $wpdb; + + $table = is_multisite() ? "{$wpdb->base_prefix}sitemeta" : "{$wpdb->base_prefix}options"; + + $like = is_multisite() ? '\\_site\\_transient\\_wu\\_pending\\_site\\_export\\_%' : '\\_transient\\_wu\\_pending\\_site\\_export\\_%'; + + $query = "SELECT meta_key, meta_value as site_id FROM {$table} WHERE meta_key LIKE '{$like}'"; + + return $wpdb->get_results($query); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery +} + +/** + * Decide how to create transients. + * + * @since 2.5.0 + * + * @param string $transient The transient key. + * @param mixed $value The transient value. + * @param int $expiration The expiration period. + * @return bool + */ +function wu_exporter_set_transient(string $transient, $value, int $expiration = 0): bool { + + global $_wp_using_ext_object_cache; + + $default_wp_using_ext_object_cache = $_wp_using_ext_object_cache; + + $_wp_using_ext_object_cache = false; + + if (is_multisite()) { + $results = set_site_transient($transient, $value, $expiration); + } else { + $results = set_transient($transient, $value, $expiration); + } + + $_wp_using_ext_object_cache = $default_wp_using_ext_object_cache; + + return $results; +} + +/** + * Decides how to delete transients. + * + * @since 2.5.0 + * + * @param string $transient The transient key. + * @return bool + */ +function wu_exporter_delete_transient(string $transient): bool { + + global $_wp_using_ext_object_cache; + + $default_wp_using_ext_object_cache = $_wp_using_ext_object_cache; + + $_wp_using_ext_object_cache = false; + + if (is_multisite()) { + $results = delete_site_transient($transient); + } else { + $results = delete_transient($transient); + } + + $_wp_using_ext_object_cache = $default_wp_using_ext_object_cache; + + return $results; +} + +/** + * Add a plugin or pattern to the exclusion list on the export zips. + * + * @since 2.5.0 + * + * @param string $plugin_or_pattern The plugin name of pattern. E.g.: wp-ultimo or wp-ultimo-*. + * @return bool + */ +function wu_exporter_exclude_plugin_from_export(string $plugin_or_pattern): bool { + + add_filter( + 'wu_site_exporter_plugin_exclusion_list', + function ($plugins_or_patterns) use ($plugin_or_pattern) { + + $plugins_or_patterns[] = $plugin_or_pattern; + + return $plugins_or_patterns; + } + ); + + return true; +} + +// -------------------------------------------------------- +// Backwards compatibility aliases for deprecated functions +// -------------------------------------------------------- + +/** + * Deprecated: Use wu_exporter_export() instead. + * + * @deprecated 2.5.0 + * + * @param int $site_id The site ID. + * @param array $options The flags on what to export. + * @param bool $async If we should generate the export file asynchronously. + * @return \WP_Error|true + */ +function wu_site_exporter_export(int $site_id, array $options = [], bool $async = false) { + + _deprecated_function(__FUNCTION__, '2.5.0', 'wu_exporter_export'); + + return wu_exporter_export($site_id, $options, $async); +} + +/** + * Deprecated: Use wu_exporter_get_all_exports() instead. + * + * @deprecated 2.5.0 + * @return array + */ +function wu_site_exporter_get_all_exports(): array { + + _deprecated_function(__FUNCTION__, '2.5.0', 'wu_exporter_get_all_exports'); + + return wu_exporter_get_all_exports(); +} + +/** + * Deprecated: Use wu_exporter_get_folder() instead. + * + * @deprecated 2.5.0 + * @return string + */ +function wu_site_exporter_get_folder(): string { + + _deprecated_function(__FUNCTION__, '2.5.0', 'wu_exporter_get_folder'); + + return wu_exporter_get_folder(); +} + +/** + * Deprecated: Use wu_exporter_get_site_from_export_name() instead. + * + * @deprecated 2.5.0 + * + * @param string $export_name The file name. + * @return \WP_Ultimo\Models\Site|false + */ +function wu_site_exporter_get_site_from_export_name(string $export_name) { + + _deprecated_function(__FUNCTION__, '2.5.0', 'wu_exporter_get_site_from_export_name'); + + return wu_exporter_get_site_from_export_name($export_name); +} + +/** + * Deprecated: Use wu_exporter_save_generation_time() instead. + * + * @deprecated 2.5.0 + * + * @param string $file The export filename. + * @param float $time The time it took. + * @return bool + */ +function wu_site_exporter_save_generation_time(string $file, float $time): bool { + + _deprecated_function(__FUNCTION__, '2.5.0', 'wu_exporter_save_generation_time'); + + return wu_exporter_save_generation_time($file, $time); +} + +/** + * Deprecated: Use wu_exporter_get_generation_time() instead. + * + * @deprecated 2.5.0 + * + * @param string $file The file name. + * @return string + */ +function wu_site_exporter_get_generation_time(string $file): string { + + _deprecated_function(__FUNCTION__, '2.5.0', 'wu_exporter_get_generation_time'); + + return wu_exporter_get_generation_time($file); +} + +/** + * Deprecated: Use wu_exporter_add_pending() instead. + * + * @deprecated 2.5.0 + * + * @param int $site_id The site ID. + * @param array $options The flags on what to export. + * @param bool $async If we should generate the export file asynchronously. + * @return string + */ +function wu_site_exporter_add_pending(int $site_id, array $options = [], bool $async = false): string { + + _deprecated_function(__FUNCTION__, '2.5.0', 'wu_exporter_add_pending'); + + return wu_exporter_add_pending($site_id, $options, $async); +} + +/** + * Deprecated: Use wu_exporter_get_pending() instead. + * + * @deprecated 2.5.0 + * @return array + */ +function wu_site_exporter_get_pending(): array { + + _deprecated_function(__FUNCTION__, '2.5.0', 'wu_exporter_get_pending'); + + return wu_exporter_get_pending(); +} + +/** + * Deprecated transient function - Use wu_exporter_set_transient() instead. + * + * @deprecated 2.5.0 + * + * @param string $transient The transient key. + * @param mixed $value The transient value. + * @param int $expiration The expiration period. + * @return bool + */ +function wp_ultimo_site_exporter_set_transient(string $transient, $value, int $expiration = 0): bool { + + return wu_exporter_set_transient($transient, $value, $expiration); +} + +/** + * Deprecated transient function - Use wu_exporter_delete_transient() instead. + * + * @deprecated 2.5.0 + * + * @param string $transient The transient key. + * @return bool + */ +function wp_ultimo_site_exporter_delete_transient(string $transient): bool { + + return wu_exporter_delete_transient($transient); +} + +/** + * Deprecated: Use wu_exporter_exclude_plugin_from_export() instead. + * + * @deprecated 2.5.0 + * + * @param string $plugin_or_pattern The plugin name of pattern. + * @return bool + */ +function wu_site_exporter_exclude_plugin_from_export(string $plugin_or_pattern): bool { + + _deprecated_function(__FUNCTION__, '2.5.0', 'wu_exporter_exclude_plugin_from_export'); + + return wu_exporter_exclude_plugin_from_export($plugin_or_pattern); +} diff --git a/inc/functions/importer.php b/inc/functions/importer.php new file mode 100644 index 00000000..119c250f --- /dev/null +++ b/inc/functions/importer.php @@ -0,0 +1,300 @@ + $file_name, + 'options' => $options, + ], + 'site-import' + ); + } + + return true; +} + +/** + * Adds a particular site import as pending. + * + * @since 2.5.0 + * + * @param string $file_name The zip file name. + * @param array $options The flags on what to import. + * @param bool $async Reserved for future use. + * @return string|\WP_Error + */ +function wu_exporter_add_pending_import(string $file_name, array $options = [], bool $async = false) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed + + if (! file_exists($file_name) || ! in_array(mime_content_type($file_name), ['application/zip', 'application/x-gzip'], true)) { + return new \WP_Error('invalid-type', __('File does not exists or it has an invalid mime-type.', 'ultimate-multisite')); + } + + $base = [ + $file_name, + $options, + ]; + + $hash = md5(serialize($base)); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize + + $base[] = $hash; + + wu_exporter_set_transient("wu_pending_site_import_{$hash}", $base, 2 * HOUR_IN_SECONDS); + + return $hash; +} + +/** + * Get pending imports. + * + * @since 2.5.0 + * @return array + */ +function wu_exporter_get_pending_imports(): array { + + global $wpdb; + + if (is_multisite()) { + $table = "{$wpdb->base_prefix}sitemeta"; + + $query = "SELECT meta_key, meta_value as options FROM {$table} WHERE meta_key LIKE '\\_site\\_transient\\_wu\\_pending\\_site\\_import\\_%'"; + } else { + $table = "{$wpdb->base_prefix}options"; + + $query = "SELECT option_name, option_value as options FROM {$table} WHERE option_name LIKE '\\_transient\\_wu\\_pending\\_site\\_import\\_%'"; + } + + $results = $wpdb->get_results($query); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery + + $results = array_map( + function ($item) { + + $item->options = maybe_unserialize($item->options); + + return $item; + }, + $results + ); + + return $results; +} + +/** + * Saves the time it took to import the zip. + * + * @since 2.5.0 + * + * @param string $file The import filename. + * @param float $time The time it took. + * @return bool + */ +function wu_exporter_save_import_time(string $file, float $time): bool { + + $times = wu_get_option('exporter_import_times', []); + + $times[ $file ] = $time; + + return wu_save_option('exporter_import_times', $times); +} + +/** + * Converts a file URL to a file path + * + * @since 2.5.0 + * + * @param string $url The file URL. + * @return string + */ +function wu_exporter_url_to_path(string $url): string { + + $path = str_replace(set_url_scheme(site_url('/'), 'https'), ABSPATH, set_url_scheme($url, 'https')); + + if (file_exists($path)) { + return $path; + } + + return get_attached_file(attachment_url_to_postid($url)); +} + +/** + * Get the site from the new url. + * + * @since 2.5.0 + * + * @param string $url The file url. + * @return \WP_Site|object|false + */ +function wu_exporter_url_to_site(string $url) { + + $parsed = wp_parse_url($url); + + if (! isset($parsed['host'])) { + return false; + } + + $site = wu_exporter_maybe_get_site_by_path($parsed['host'], $parsed['path'] ?? ''); + + return $site; +} + +/** + * Gets a site by domain and path. + * + * @since 2.5.0 + * + * @param string $domain The site domain. + * @param string $path The site path. + * @return \WP_Site|object|false + */ +function wu_exporter_maybe_get_site_by_path(string $domain, string $path) { + + if (is_multisite()) { + return get_site_by_path($domain, $path); + } else { + return (object) [ + 'blog_id' => 1, + ]; + } +} + +// -------------------------------------------------------- +// Backwards compatibility aliases for deprecated functions +// -------------------------------------------------------- + +/** + * Deprecated: Use wu_exporter_import() instead. + * + * @deprecated 2.5.0 + * + * @param string $file_name The zip file name. + * @param array $options The flags on what to import. + * @param bool $async If we should generate the import file asynchronously. + * @return \WP_Error|true + */ +function wu_site_exporter_import(string $file_name, array $options = [], bool $async = true) { + + _deprecated_function(__FUNCTION__, '2.5.0', 'wu_exporter_import'); + + return wu_exporter_import($file_name, $options, $async); +} + +/** + * Deprecated: Use wu_exporter_add_pending_import() instead. + * + * @deprecated 2.5.0 + * + * @param string $file_name The zip file name. + * @param array $options The flags on what to import. + * @param bool $async If we should generate the import file asynchronously. + * @return string|\WP_Error + */ +function wu_site_exporter_add_pending_import(string $file_name, array $options = [], bool $async = false) { + + _deprecated_function(__FUNCTION__, '2.5.0', 'wu_exporter_add_pending_import'); + + return wu_exporter_add_pending_import($file_name, $options, $async); +} + +/** + * Deprecated: Use wu_exporter_get_pending_imports() instead. + * + * @deprecated 2.5.0 + * @return array + */ +function wu_site_exporter_get_pending_imports(): array { + + _deprecated_function(__FUNCTION__, '2.5.0', 'wu_exporter_get_pending_imports'); + + return wu_exporter_get_pending_imports(); +} + +/** + * Deprecated: Use wu_exporter_save_import_time() instead. + * + * @deprecated 2.5.0 + * + * @param string $file The import filename. + * @param float $time The time it took. + * @return bool + */ +function wu_site_exporter_save_import_time(string $file, float $time): bool { + + _deprecated_function(__FUNCTION__, '2.5.0', 'wu_exporter_save_import_time'); + + return wu_exporter_save_import_time($file, $time); +} + +/** + * Deprecated: Use wu_exporter_url_to_path() instead. + * + * @deprecated 2.5.0 + * + * @param string $url The file URL. + * @return string + */ +function wu_site_exporter_url_to_path(string $url): string { + + _deprecated_function(__FUNCTION__, '2.5.0', 'wu_exporter_url_to_path'); + + return wu_exporter_url_to_path($url); +} + +/** + * Deprecated: Use wu_exporter_url_to_site() instead. + * + * @deprecated 2.5.0 + * + * @param string $url The file url. + * @return \WP_Site|object|false + */ +function wu_site_exporter_url_to_site(string $url) { + + _deprecated_function(__FUNCTION__, '2.5.0', 'wu_exporter_url_to_site'); + + return wu_exporter_url_to_site($url); +} + +/** + * Deprecated: Use wu_exporter_maybe_get_site_by_path() instead. + * + * @deprecated 2.5.0 + * + * @param string $domain The site domain. + * @param string $path The site path. + * @return \WP_Site|object|false + */ +function wp_ultimo_site_exporter_maybe_get_site_by_path(string $domain, string $path) { + + return wu_exporter_maybe_get_site_by_path($domain, $path); +} diff --git a/inc/helpers/class-hash.php b/inc/helpers/class-hash.php index 4582c565..f75ba98b 100644 --- a/inc/helpers/class-hash.php +++ b/inc/helpers/class-hash.php @@ -40,7 +40,7 @@ private function __construct() {} * @param string $group Hash group. Used to increase entropy. * @return string */ - public static function encode($number, $group = 'wp-ultimo') { + public static function encode($number, $group = 'ultimate-multisite') { $hasher = new Hashids($group, self::LENGTH, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'); @@ -56,7 +56,7 @@ public static function encode($number, $group = 'wp-ultimo') { * @param string $group Hash group. Used to increase entropy. * @return string|int */ - public static function decode($hash, $group = 'wp-ultimo') { + public static function decode($hash, $group = 'ultimate-multisite') { $hasher = new Hashids($group, 10, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'); diff --git a/inc/helpers/validation-rules/class-unique-customer-email.php b/inc/helpers/validation-rules/class-unique-customer-email.php new file mode 100644 index 00000000..6fb74f36 --- /dev/null +++ b/inc/helpers/validation-rules/class-unique-customer-email.php @@ -0,0 +1,86 @@ +message = __('A customer with the same email address already exists.', 'ultimate-multisite'); + + global $wpdb; + + // Query for users with this exact email address across the entire network + // We use a direct query to ensure exact email matching (not LIKE) + $user_ids = $wpdb->get_col( + $wpdb->prepare( + "SELECT ID FROM {$wpdb->users} WHERE user_email = %s", + $value + ) + ); + + // No users with this email exist, so no customer can exist + if (empty($user_ids)) { + return true; + } + + // Check if any of these users are linked to an Ultimate Multisite customer + foreach ($user_ids as $user_id) { + $customer = wu_get_customer_by_user_id($user_id); + + if ($customer) { + // A customer with this email already exists + return false; + } + } + + // No customer found with this email + return true; + } +} diff --git a/inc/models/class-membership.php b/inc/models/class-membership.php index 4272774b..c07bebdf 100644 --- a/inc/models/class-membership.php +++ b/inc/models/class-membership.php @@ -1945,7 +1945,7 @@ public function publish_pending_site_async(): void { if (is_wp_error($result)) { // translators: %s full error message. - wu_log_add("membership-{$this->get_id()}", sprintf(__('Failed to trigger async site creation. The site will not be created until the next cron run which is much slower: %s'), $result->get_error_message())); + wu_log_add("membership-{$this->get_id()}", sprintf(__('Failed to trigger async site creation. The site will not be created until the next cron run which is much slower: %s', 'ultimate-multisite'), $result->get_error_message())); } wu_enqueue_async_action('wu_async_publish_pending_site', ['membership_id' => $this->get_id()], 'membership'); diff --git a/inc/site-exporter/class-site-exporter.php b/inc/site-exporter/class-site-exporter.php new file mode 100644 index 00000000..2900dc4f --- /dev/null +++ b/inc/site-exporter/class-site-exporter.php @@ -0,0 +1,1625 @@ +setup(); + + $this->loaded = true; + + /** + * Triggers when all the dependencies were loaded. + * + * Allows plugin developers to add new functionality. For example, support to new + * Hosting providers, etc. + * + * @since 2.5.0 + */ + do_action('wu_site_exporter_loaded'); + + // Backwards compatibility + do_action('wp_ultimo_site_exporter_load'); + } + + /** + * Adds the necessary hooks to deal with exports and imports. + * + * @since 2.5.0 + * @return void + */ + public function setup(): void { + + add_action('wu_export_site', [$this, 'handle_site_export'], 10, 3); + + add_action('wu_import_site', [$this, 'handle_site_import'], 10, 3); + + add_filter('wu_site_exporter_files_to_zip', [$this, 'maybe_exclude_wp_ultimo_plugins']); + + add_action('cron_schedules', [$this, 'maybe_add_schedule']); + + add_action('init', [$this, 'maybe_run_imports']); + + // Register admin forms and hooks + add_action('wu_register_forms', [$this, 'register_forms']); + + // Add export/import action links to Sites list page + add_filter('wu_site_list_page_action_links', [$this, 'add_site_list_action_links']); + + // Add export widget to Site edit page + add_action('wu_edit_site_page_register_widgets', [$this, 'register_site_edit_widgets']); + + // Handle import form submission + add_action('admin_init', [$this, 'maybe_handle_import']); + + // Add bulk export action + add_filter('wu_site_bulk_actions', [$this, 'add_bulk_export_action']); + add_action('wu_handle_bulk_action_form_site_export', [$this, 'handle_bulk_export'], 10, 3); + + // WordPress default Sites page integration (works without Ultimate Multisite setup) + $this->setup_wordpress_sites_integration(); + } + + /** + * Set up integration with the default WordPress Sites page. + * + * This allows exporting sites even before Ultimate Multisite is fully set up, + * making migration from other solutions easier. + * + * @since 2.5.0 + * @return void + */ + private function setup_wordpress_sites_integration(): void { + + // Add export action link to each site row + add_filter('manage_sites_action_links', [$this, 'add_wp_sites_row_actions'], 10, 2); + + // Add bulk export action + add_filter('bulk_actions-sites-network', [$this, 'add_wp_sites_bulk_actions']); + + // Handle bulk export action + add_filter('handle_network_bulk_actions-sites-network', [$this, 'handle_wp_sites_bulk_action'], 10, 3); + + // Add admin menu page for export/import + add_action('network_admin_menu', [$this, 'add_wp_export_menu_page']); + + // Handle direct export requests + add_action('admin_init', [$this, 'handle_direct_export_request']); + + // Display admin notices + add_action('network_admin_notices', [$this, 'display_export_notices']); + + // Enqueue scripts for WordPress sites page + add_action('admin_enqueue_scripts', [$this, 'enqueue_wp_sites_scripts']); + } + + /** + * Add export action link to WordPress Sites page rows. + * + * @since 2.5.0 + * + * @param array $actions Existing actions. + * @param int $blog_id The blog ID. + * @return array + */ + public function add_wp_sites_row_actions(array $actions, int $blog_id): array { + + // Don't add for main site + if (is_main_site($blog_id)) { + return $actions; + } + + $export_url = add_query_arg( + [ + 'page' => 'wu-site-export', + 'site_id' => $blog_id, + 'action' => 'export', + ], + network_admin_url('sites.php') + ); + + $actions['export'] = sprintf( + '%s', + esc_url($export_url), + __('Export', 'ultimate-multisite') + ); + + return $actions; + } + + /** + * Add bulk export action to WordPress Sites page. + * + * @since 2.5.0 + * + * @param array $actions Existing bulk actions. + * @return array + */ + public function add_wp_sites_bulk_actions(array $actions): array { + + $actions['export'] = __('Export', 'ultimate-multisite'); + + return $actions; + } + + /** + * Handle bulk export action from WordPress Sites page. + * + * @since 2.5.0 + * + * @param string $redirect_url The redirect URL. + * @param string $action The action being performed. + * @param array $blog_ids The selected blog IDs. + * @return string + */ + public function handle_wp_sites_bulk_action(string $redirect_url, string $action, array $blog_ids): string { + + if ('export' !== $action) { + return $redirect_url; + } + + $exported = 0; + + foreach ($blog_ids as $blog_id) { + // Skip main site + if (is_main_site($blog_id)) { + continue; + } + + wu_exporter_export($blog_id, ['uploads' => true], true); + ++$exported; + } + + return add_query_arg( + [ + 'page' => 'wu-site-export', + 'bulk_exported' => $exported, + ], + network_admin_url('sites.php') + ); + } + + /** + * Add export/import menu page under Sites. + * + * @since 2.5.0 + * @return void + */ + public function add_wp_export_menu_page(): void { + + add_submenu_page( + 'sites.php', + __('Export & Import Sites', 'ultimate-multisite'), + __('Export & Import', 'ultimate-multisite'), + 'manage_network', + 'wu-site-export', + [$this, 'render_wp_export_page'] + ); + } + + /** + * Render the export/import page. + * + * @since 2.5.0 + * @return void + */ + public function render_wp_export_page(): void { + + $site_id = absint(wu_request('site_id', 0)); + $action = wu_request('action', ''); + + // Get exports and pending items + $exports = wu_exporter_get_all_exports(); + $pending_exports = function_exists('wu_exporter_get_pending') ? wu_exporter_get_pending() : []; + $pending_imports = wu_exporter_get_pending_imports(); + + ?> +
+

+ + + render_export_form($site_id); ?> + + render_export_import_dashboard($exports, $pending_exports, $pending_imports); ?> + +
+ 'wu-site-export', + 'action' => 'do_export', + 'site_id' => $site_id, + ], + network_admin_url('sites.php') + ), + 'wu_export_site_' . $site_id + ); + + ?> +
+

+ +

+ ' . esc_html($blog_details->blogname) . ' (' . esc_html($blog_details->siteurl) . ')' + ); + ?> +

+ +
+ + + + + + + + + + + + + + + + + +
+ +
+ +
+ +
+ +
+ +

+ + +

+
+
+ +
+

+

+

+ + + +

+
+ + +
+

+

+ + + + + + + + + + + + + + + +
options[0] ?? __('Unknown', 'ultimate-multisite')); ?>
+
+ + + +
+

+

+ + + + + + + + + + $pending) : ?> + + + + + + + +
options[0] ?? '')); ?>options[1]['new_url'] ?? ''); ?> + + + +
+
+ + +
+

+ + +

+ + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ +
+ +
+

+

+ +
+ + + + + + + + + + + + + +
+ + +

+
+ +

+
+ +
+ +

+ +

+
+
+ ! empty($_POST['include_themes']), + 'plugins' => ! empty($_POST['include_plugins']), + 'uploads' => ! empty($_POST['include_uploads']), + ]; + + $background = ! empty($_POST['background_run']); + + wu_exporter_export($site_id, $options, $background); + + $message = $background ? 'export_started' : 'export_complete'; + + wp_safe_redirect( + add_query_arg( + [ + 'page' => 'wu-site-export', + 'message' => $message, + ], + network_admin_url('sites.php') + ) + ); + exit; + } + + // Handle delete + if ('delete' === $action) { + $file = wu_request('file', ''); + + if (! wp_verify_nonce(wu_request('_wpnonce'), 'wu_delete_export')) { + wp_die(esc_html__('Security check failed.', 'ultimate-multisite')); + } + + if (! current_user_can('manage_network')) { + wp_die(esc_html__('You do not have permission to delete exports.', 'ultimate-multisite')); + } + + // Validate file name format for security + if (preg_match('/^wu-site-export-[0-9]+-/', $file)) { + $path = wu_maybe_create_folder('wu-site-exports') . $file; + + if (file_exists($path)) { + wp_delete_file($path); + } + } + + wp_safe_redirect( + add_query_arg( + [ + 'page' => 'wu-site-export', + 'message' => 'deleted', + ], + network_admin_url('sites.php') + ) + ); + exit; + } + + // Handle import + if ('import' === $action && isset($_POST['zip_url'])) { + if (! wp_verify_nonce(wu_request('_wpnonce'), 'wu_import_site')) { + wp_die(esc_html__('Security check failed.', 'ultimate-multisite')); + } + + if (! current_user_can('manage_network')) { + wp_die(esc_html__('You do not have permission to import sites.', 'ultimate-multisite')); + } + + $zip_url = sanitize_text_field(wp_unslash($_POST['zip_url'])); + $new_url = sanitize_text_field(wp_unslash($_POST['new_url'] ?? '')); + $delete_zip = ! empty($_POST['delete_zip']); + + if (empty($zip_url) || empty($new_url)) { + wp_safe_redirect( + add_query_arg( + [ + 'page' => 'wu-site-export', + 'message' => 'import_error', + 'error' => 'missing_fields', + ], + network_admin_url('sites.php') + ) + ); + exit; + } + + $file_path = $this->url_to_path($zip_url); + + if (! $file_path || ! file_exists($file_path)) { + wp_safe_redirect( + add_query_arg( + [ + 'page' => 'wu-site-export', + 'message' => 'import_error', + 'error' => 'file_not_found', + ], + network_admin_url('sites.php') + ) + ); + exit; + } + + wu_exporter_import( + $file_path, + [ + 'delete_file' => $delete_zip, + 'zip_url' => $zip_url, + 'url' => $new_url, + 'new_url' => $new_url, + ] + ); + + wp_safe_redirect( + add_query_arg( + [ + 'page' => 'wu-site-export', + 'message' => 'import_started', + ], + network_admin_url('sites.php') + ) + ); + exit; + } + } + + /** + * Display admin notices for export/import actions. + * + * @since 2.5.0 + * @return void + */ + public function display_export_notices(): void { + + $message = wu_request('message', ''); + $bulk_exported = absint(wu_request('bulk_exported', 0)); + + if ($bulk_exported > 0) { + printf( + '

%s

', + /* translators: %d number of sites */ + esc_html(sprintf(_n('%d site export started in background.', '%d site exports started in background.', $bulk_exported, 'ultimate-multisite'), $bulk_exported)) + ); + } + + switch ($message) { + case 'export_complete': + echo '

' . esc_html__('Site exported successfully!', 'ultimate-multisite') . '

'; + break; + case 'export_started': + echo '

' . esc_html__('Site export started in background. Check back shortly.', 'ultimate-multisite') . '

'; + break; + case 'deleted': + echo '

' . esc_html__('Export deleted successfully.', 'ultimate-multisite') . '

'; + break; + case 'import_started': + echo '

' . esc_html__('Site import started. The site will be available shortly.', 'ultimate-multisite') . '

'; + break; + case 'import_error': + $error = wu_request('error', ''); + $error_messages = [ + 'missing_fields' => __('Please provide both a ZIP file URL and target URL.', 'ultimate-multisite'), + 'file_not_found' => __('The ZIP file could not be found. Make sure it is uploaded to this site.', 'ultimate-multisite'), + ]; + $error_text = $error_messages[ $error ] ?? __('An error occurred during import.', 'ultimate-multisite'); + echo '

' . esc_html($error_text) . '

'; + break; + } + } + + /** + * Enqueue scripts for WordPress Sites page. + * + * @since 2.5.0 + * + * @param string $hook The current admin page hook. + * @return void + */ + public function enqueue_wp_sites_scripts(string $hook): void { + + if ('sites_page_wu-site-export' !== $hook) { + return; + } + + wp_enqueue_media(); + + wp_add_inline_script( + 'media-editor', + " + jQuery(document).ready(function($) { + $('#wu-wp-upload-zip').on('click', function(e) { + e.preventDefault(); + var frame = wp.media({ + title: '" . esc_js(__('Select or Upload ZIP File', 'ultimate-multisite')) . "', + button: { text: '" . esc_js(__('Use this file', 'ultimate-multisite')) . "' }, + multiple: false + }); + frame.on('select', function() { + var attachment = frame.state().get('selection').first().toJSON(); + $('#zip_url').val(attachment.url); + }); + frame.open(); + }); + }); + " + ); + + // Add spinning animation for pending exports + wp_add_inline_style( + 'common', + ' + .dashicons.spin { + animation: wu-spin 1s linear infinite; + } + @keyframes wu-spin { + from { transform: rotate(0deg); } + to { transform: rotate(360deg); } + } + ' + ); + } + + /** + * Register export/import forms. + * + * @since 2.5.0 + * @return void + */ + public function register_forms(): void { + + wu_register_form( + 'export_site', + [ + 'render' => [$this, 'render_export_site_modal'], + 'handler' => [$this, 'handle_export_site_modal'], + 'capability' => 'manage_network', + ] + ); + + wu_register_form( + 'import_site', + [ + 'render' => [$this, 'render_import_site_modal'], + 'handler' => [$this, 'handle_import_site_modal'], + 'capability' => 'manage_network', + ] + ); + + wu_register_form( + 'delete_export', + [ + 'render' => [$this, 'render_delete_export_modal'], + 'handler' => [$this, 'handle_delete_export_modal'], + 'capability' => 'manage_network', + ] + ); + } + + /** + * Renders the export site modal. + * + * @since 2.5.0 + * @return void + */ + public function render_export_site_modal(): void { + + $site_id = wu_request('id'); + $site = wu_get_site($site_id); + + $fields = [ + 'exporting_site' => [ + 'type' => 'model', + 'title' => __('Site to Export', 'ultimate-multisite'), + 'placeholder' => __('Search Sites...', 'ultimate-multisite'), + 'desc' => __('The site will be exported to a .zip file that can be imported into any Ultimate Multisite network.', 'ultimate-multisite'), + 'value' => '', + 'html_attr' => [ + 'data-model' => 'site', + 'data-selected' => $site ? wp_json_encode($site->to_search_results()) : '', + 'data-value-field' => 'blog_id', + 'data-label-field' => 'title', + 'data-search-field' => 'title', + 'data-max-items' => 1, + ], + ], + 'include_themes' => [ + 'type' => 'toggle', + 'title' => __('Include Themes', 'ultimate-multisite'), + 'desc' => __('Include the active theme and parent theme if applicable.', 'ultimate-multisite'), + 'value' => false, + ], + 'include_plugins' => [ + 'type' => 'toggle', + 'title' => __('Include Plugins', 'ultimate-multisite'), + 'desc' => __('Include active plugins in the export.', 'ultimate-multisite'), + 'value' => false, + ], + 'include_uploads' => [ + 'type' => 'toggle', + 'title' => __('Include Uploads', 'ultimate-multisite'), + 'desc' => __('Include media files from the uploads folder.', 'ultimate-multisite'), + 'value' => true, + ], + 'background_run' => [ + 'type' => 'toggle', + 'title' => __('Run in Background', 'ultimate-multisite'), + 'desc' => __('For large sites, run the export as a background process.', 'ultimate-multisite'), + 'value' => false, + ], + 'submit_button' => [ + 'type' => 'submit', + 'title' => __('Export Site', 'ultimate-multisite'), + 'value' => 'save', + 'classes' => 'button button-primary wu-w-full', + 'wrapper_classes' => 'wu-items-end wu-text-right', + ], + ]; + + $form = new \WP_Ultimo\UI\Form( + 'export_site', + $fields, + [ + 'views' => 'admin-pages/fields', + 'classes' => 'wu-modal-form wu-widget-list wu-striped wu-m-0 wu-mt-0', + 'field_wrapper_classes' => 'wu-w-full wu-box-border wu-items-center wu-flex wu-justify-between wu-p-4 wu-m-0 wu-border-t wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300 wu-border-solid', + ] + ); + + $form->render(); + } + + /** + * Handles the export site modal submission. + * + * @since 2.5.0 + * @return void + */ + public function handle_export_site_modal(): void { + + $site_id = wu_request('exporting_site', ''); + $site = wu_get_site($site_id); + + if (! $site) { + wp_send_json_error(new \WP_Error('invalid-site', __('Invalid site selected.', 'ultimate-multisite'))); + } + + wu_exporter_export( + $site_id, + [ + 'plugins' => wu_request('include_plugins'), + 'themes' => wu_request('include_themes'), + 'uploads' => wu_request('include_uploads'), + ], + wu_request('background_run') + ); + + $message = wu_request('background_run') + ? __('Export started in background...', 'ultimate-multisite') + : __('Export completed!', 'ultimate-multisite'); + + wp_send_json_success( + [ + 'redirect_url' => wu_network_admin_url('wp-ultimo-sites', ['updated' => $message]), + ] + ); + } + + /** + * Renders the import site modal. + * + * @since 2.5.0 + * @return void + */ + public function render_import_site_modal(): void { + + $this->reset_upload_limits(); + + $fields = [ + 'zip_file' => [ + 'type' => 'text', + 'title' => __('ZIP File URL', 'ultimate-multisite'), + 'placeholder' => __('https://example.com/export.zip', 'ultimate-multisite'), + 'desc' => __('Enter the URL to the export ZIP file, or use the media uploader.', 'ultimate-multisite'), + 'html_attr' => [ + 'id' => 'wu-import-zip-url', + ], + ], + 'upload_btn' => [ + 'type' => 'html', + 'content' => sprintf( + '', + __('Upload ZIP File', 'ultimate-multisite') + ), + 'wrapper_classes' => 'wu-mb-4', + ], + 'new_url' => [ + 'type' => 'text', + 'title' => __('New Site URL', 'ultimate-multisite'), + 'placeholder' => is_subdomain_install() ? 'newsite.example.com' : 'example.com/newsite', + 'desc' => __('The URL for the new imported site.', 'ultimate-multisite'), + ], + 'remove_zip' => [ + 'type' => 'toggle', + 'title' => __('Delete ZIP After Import', 'ultimate-multisite'), + 'desc' => __('Remove the ZIP file after successful import.', 'ultimate-multisite'), + 'value' => true, + ], + 'submit_button' => [ + 'type' => 'submit', + 'title' => __('Import Site', 'ultimate-multisite'), + 'value' => 'save', + 'classes' => 'button button-primary wu-w-full', + 'wrapper_classes' => 'wu-items-end wu-text-right', + ], + ]; + + $form = new \WP_Ultimo\UI\Form( + 'import_site', + $fields, + [ + 'views' => 'admin-pages/fields', + 'classes' => 'wu-modal-form wu-widget-list wu-striped wu-m-0 wu-mt-0', + 'field_wrapper_classes' => 'wu-w-full wu-box-border wu-items-center wu-flex wu-justify-between wu-p-4 wu-m-0 wu-border-t wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300 wu-border-solid', + ] + ); + + $form->render(); + + // Add media uploader script + ?> + + url_to_path($zip_url); + + if (! $file_path || ! file_exists($file_path)) { + wp_send_json_error(new \WP_Error('file-not-found', __('ZIP file not found.', 'ultimate-multisite'))); + } + + $result = wu_exporter_import( + $file_path, + [ + 'delete_file' => wu_request('remove_zip'), + 'zip_url' => $zip_url, + 'url' => $new_url, + 'new_url' => $new_url, + ] + ); + + if (is_wp_error($result)) { + wp_send_json_error($result); + } + + wp_send_json_success( + [ + 'redirect_url' => wu_network_admin_url('wp-ultimo-sites', ['updated' => __('Import process started.', 'ultimate-multisite')]), + ] + ); + } + + /** + * Renders the delete export modal. + * + * @since 2.5.0 + * @return void + */ + public function render_delete_export_modal(): void { + + $export_name = wu_request('file_name'); + + $fields = [ + 'confirm' => [ + 'type' => 'toggle', + 'title' => __('Confirm Deletion', 'ultimate-multisite'), + 'desc' => __('This action cannot be undone.', 'ultimate-multisite'), + 'value' => false, + 'html_attr' => [ + 'v-model' => 'confirm', + ], + ], + 'file_name' => [ + 'type' => 'hidden', + 'value' => $export_name, + ], + 'submit_button' => [ + 'type' => 'submit', + 'title' => __('Delete Export', 'ultimate-multisite'), + 'value' => 'save', + 'classes' => 'button button-primary wu-w-full', + 'wrapper_classes' => 'wu-items-end wu-text-right', + 'html_attr' => [ + 'v-bind:disabled' => '!confirm', + ], + ], + ]; + + $form = new \WP_Ultimo\UI\Form( + 'delete_export', + $fields, + [ + 'views' => 'admin-pages/fields', + 'classes' => 'wu-modal-form wu-widget-list wu-striped wu-m-0 wu-mt-0', + 'field_wrapper_classes' => 'wu-w-full wu-box-border wu-items-center wu-flex wu-justify-between wu-p-4 wu-m-0 wu-border-t wu-border-l-0 wu-border-r-0 wu-border-b-0 wu-border-gray-300 wu-border-solid', + 'html_attr' => [ + 'data-wu-app' => 'delete_export', + 'data-state' => wu_convert_to_state(['confirm' => false]), + ], + ] + ); + + $form->render(); + } + + /** + * Handles the delete export modal submission. + * + * @since 2.5.0 + * @return void + */ + public function handle_delete_export_modal(): void { + + $export_name = wu_request('file_name'); + + if (empty($export_name)) { + wp_send_json_error(new \WP_Error('invalid-export', __('Invalid export file.', 'ultimate-multisite'))); + } + + // Validate file name format for security + if (! preg_match('/^wu-site-export-[0-9]+-/', $export_name)) { + wp_send_json_error(new \WP_Error('invalid-export', __('Invalid export file name.', 'ultimate-multisite'))); + } + + $path = wu_maybe_create_folder('wu-site-exports') . $export_name; + + if (! file_exists($path)) { + wp_send_json_error(new \WP_Error('not-found', __('Export file not found.', 'ultimate-multisite'))); + } + + $success = wp_delete_file($path); + + wp_send_json_success( + [ + 'redirect_url' => wu_network_admin_url('wp-ultimo-sites', ['deleted' => 1]), + ] + ); + } + + /** + * Add action links to Sites list page. + * + * @since 2.5.0 + * + * @param array $links Existing action links. + * @return array + */ + public function add_site_list_action_links(array $links): array { + + $links[] = [ + 'label' => __('Export Site', 'ultimate-multisite'), + 'icon' => 'wu-export', + 'classes' => 'wubox', + 'url' => wu_get_form_url('export_site'), + ]; + + $links[] = [ + 'label' => __('Import Site', 'ultimate-multisite'), + 'icon' => 'wu-import', + 'classes' => 'wubox', + 'url' => wu_get_form_url('import_site'), + ]; + + return $links; + } + + /** + * Register export widget on Site edit page. + * + * @since 2.5.0 + * + * @param \WP_Ultimo\Admin_Pages\Site_Edit_Admin_Page $page The edit page instance. + * @return void + */ + public function register_site_edit_widgets($page): void { + + $site = $page->get_object(); + + if (! $site) { + return; + } + + $exports = wu_exporter_get_all_exports(); + $site_exports = array_filter( + $exports, + function ($export) use ($site) { + return strpos($export['file'], 'wu-site-export-' . $site->get_id() . '-') !== false; + } + ); + + $export_url = wu_get_form_url('export_site', ['id' => $site->get_id()]); + + $page->add_fields_widget( + 'site_export', + [ + 'title' => __('Site Export', 'ultimate-multisite'), + 'position' => 'side', + 'fields' => [ + 'export_button' => [ + 'type' => 'html', + 'wrapper_classes' => 'wu-bg-gray-100', + 'content' => sprintf( + '%s', + esc_url($export_url), + __('Export This Site', 'ultimate-multisite') + ), + ], + 'export_list' => [ + 'type' => 'html', + 'content' => $this->render_site_exports_list($site_exports, $site), + ], + ], + ] + ); + } + + /** + * Render the list of exports for a site. + * + * @since 2.5.0 + * + * @param array $exports The exports list. + * @param \WP_Ultimo\Models\Site $site The site object (reserved for future use). + * @return string + */ + private function render_site_exports_list(array $exports, $site): string { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed + + if (empty($exports)) { + return sprintf( + '

%s

', + __('No exports available for this site.', 'ultimate-multisite') + ); + } + + $html = '
' . __('Previous Exports:', 'ultimate-multisite') . '
    '; + + foreach (array_slice($exports, 0, 5) as $export) { + $delete_url = wu_get_form_url('delete_export', ['file_name' => $export['file']]); + + $html .= sprintf( + '
  • + %s + %s +
  • ', + esc_url($export['url']), + esc_html($export['date']), + esc_url($delete_url), + __('Delete', 'ultimate-multisite') + ); + } + + $html .= '
'; + + return $html; + } + + /** + * Add bulk export action. + * + * @since 2.5.0 + * + * @param array $actions Existing bulk actions. + * @return array + */ + public function add_bulk_export_action(array $actions): array { + + $actions['export'] = __('Export Sites', 'ultimate-multisite'); + + return $actions; + } + + /** + * Handle bulk export action. + * + * @since 2.5.0 + * + * @param string $action The action name. + * @param string $model The model name. + * @param array $ids The selected IDs. + * @return void + */ + public function handle_bulk_export($action, $model, $ids): void { + + $item_ids = array_filter($ids); + + foreach ($item_ids as $item_id) { + wu_exporter_export($item_id, ['uploads' => true], true); + } + } + + /** + * Reset upload limits for importing. + * + * @since 2.5.0 + * @return void + */ + public function reset_upload_limits(): void { + + @ini_set('upload_max_size', '2048M'); // phpcs:ignore + @ini_set('post_max_size', '2064M'); // phpcs:ignore + @ini_set('max_execution_time', '0'); // phpcs:ignore + + if (is_main_site()) { + add_filter( + 'upload_mimes', + function ($mimes) { + $mimes['zip'] = 'application/zip'; + $mimes['gz'] = 'application/x-gzip'; + return $mimes; + }, + 999 + ); + + if (! defined('ALLOW_UNFILTERED_UPLOADS')) { + define('ALLOW_UNFILTERED_UPLOADS', true); + } + + add_filter('get_space_allowed', fn() => 999999); + } + } + + /** + * Handle import form submission (non-AJAX). + * + * @since 2.5.0 + * @return void + */ + public function maybe_handle_import(): void { + + if (! wu_request('wu-cancel-import')) { + return; + } + + check_admin_referer('wu-cancel-import'); + + $hash = wu_request('wu-cancel-import'); + + wu_exporter_delete_transient("wu_pending_site_import_{$hash}"); + + wp_safe_redirect( + add_query_arg( + 'error', + __('Import cancelled.', 'ultimate-multisite'), + remove_query_arg(['updated', 'wu-cancel-import', '_wpnonce']) + ) + ); + + exit; + } + + /** + * Convert URL to local file path. + * + * @since 2.5.0 + * + * @param string $url The URL to convert. + * @return string|false + */ + private function url_to_path(string $url) { + + $upload_dir = wp_upload_dir(); + $base_url = $upload_dir['baseurl']; + $base_dir = $upload_dir['basedir']; + + if (strpos($url, $base_url) === 0) { + return str_replace($base_url, $base_dir, $url); + } + + return false; + } + + /** + * Maybe exclude WP Ultimo and other plugins from the generated zip. + * + * @since 2.5.0 + * + * @param array $files_to_zip The files to be zipped. + * @return array + */ + public function maybe_exclude_wp_ultimo_plugins(array $files_to_zip): array { + + if (isset($files_to_zip['wp-content/plugins'])) { + $plugins_folder = $files_to_zip['wp-content/plugins']; + + /** + * Allows developers to manage a plugin list that maybe exclude from the generated zip. + * + * @since 2.5.0 + * + * @param array $plugin_list The plugins that will be excluded. + * @return array The plugin list. + */ + $not_name = apply_filters( + 'wu_site_exporter_plugin_exclusion_list', + [ + 'wp-ultimo*', + 'ultimate-multisite*', + ] + ); + + $plugins = Finder::create() + ->depth('== 0') + ->ignoreVCS(true) + ->notName($not_name) + ->in($plugins_folder); + + foreach ($plugins as $plugin) { + $files_to_zip[ 'wp-content/plugins/' . $plugin->getRelativePathname() ] = $plugin->getPathName(); + } + + unset($files_to_zip['wp-content/plugins']); + } + + return $files_to_zip; + } + + /** + * Maybe adds the the hook to the cron. + * + * @since 2.5.0 + * @return void + */ + public function maybe_run_imports(): void { + + if (! wp_next_scheduled('wu_import_site')) { + wp_schedule_event(time() + 10, 'wu_site_every_minute', 'wu_import_site'); + } + } + + /** + * Maybe adds a new schedule. + * + * @since 2.5.0 + * + * @param array $schedules The list of available schedules. + * @return array + */ + public function maybe_add_schedule(array $schedules): array { + + $pending_imports = wu_exporter_get_pending_imports(); + + if (empty($pending_imports)) { + return $schedules; + } + + $schedules['wu_site_every_minute'] = [ + 'interval' => 60, + 'display' => esc_html__('Every 60 Seconds', 'ultimate-multisite'), + ]; + + return $schedules; + } + + /** + * Handles a site export generation. + * + * @since 2.5.0 + * + * @param int $site_id The ID of the site being exported. + * @param array $options Export generation options. + * @param string $hash The hash generated. + * @return bool + */ + public function handle_site_export(int $site_id, array $options = [], string $hash = ''): bool { + + $this->load_dependencies(); + + $export_name = sprintf('wu-site-export-%s-%s-%s.zip', $site_id, gmdate('Y-m-d'), time()); + + $command = new \TenUp\MU_Migration\Commands\ExportCommand(); + + $base_path = wu_maybe_create_folder('wu-site-exports'); + + $args = [ + 'blog_id' => $site_id, + ]; + + if (wu_get_isset($options, 'plugins')) { + $args['plugins'] = 1; + } + + if (wu_get_isset($options, 'themes')) { + $args['themes'] = 1; + } + + if (wu_get_isset($options, 'uploads')) { + $args['uploads'] = 1; + } + + $start = microtime(true); + + $command->all([$base_path . $export_name], $args); + + $time = microtime(true) - $start; + + wu_exporter_save_generation_time($export_name, $time); + + wu_exporter_delete_transient("wu_pending_site_export_{$hash}"); + + return true; + } + + /** + * Handles the site import. + * + * @since 2.5.0 + * @return bool + */ + public function handle_site_import(): bool { + + $pending_imports = wu_exporter_get_pending_imports(); + + if (empty($pending_imports)) { + return false; + } + + $file_name = ''; + $options = []; + $hash = ''; + + foreach ($pending_imports as $pi) { + if (! isset($pi->options[1]['running'])) { + $file_name = $pi->options[0]; + $options = $pi->options[1]; + $hash = $pi->options[2]; + + break; + } + } + + if (empty($file_name)) { + return false; + } + + $options['running'] = false; + + $base = [ + $file_name, + $options, + $hash, + ]; + + wu_exporter_set_transient("wu_pending_site_import_{$hash}", $base, 2 * HOUR_IN_SECONDS); + + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + require_once ABSPATH . 'wp-admin/includes/theme.php'; + + $this->load_dependencies(); + + $command = new \TenUp\MU_Migration\Commands\ImportCommand(); + + $defaults = [ + 'url' => '', + 'new_url' => '', + 'zip_url' => '', + 'delete_zip' => true, + 'mysql-single-transaction' => true, + ]; + + $args = wp_parse_args($options, $defaults); + + $start = microtime(true); + + $command->all([$file_name], $args); + + $time = microtime(true) - $start; + + wu_exporter_save_import_time($file_name, $time); + + wu_exporter_delete_transient("wu_pending_site_import_{$hash}"); + + $delete_file = isset($options['delete_file']); + + if ($delete_file) { + $attachment_id = attachment_url_to_postid($options['zip_url']); + + wp_delete_attachment($attachment_id, true); + } + + return true; + } + + /** + * Load the commands from mu-migration. + * + * @since 2.5.0 + * @return void + */ + public function load_dependencies(): void { + + $base_path = wu_path('inc/site-exporter/mu-migration'); + + if (file_exists($base_path . '/vendor/autoload.php')) { + require_once $base_path . '/vendor/autoload.php'; + require_once $base_path . '/includes/helpers.php'; + require_once $base_path . '/includes/commands/class-mu-migration.php'; + require_once $base_path . '/includes/commands/class-mu-migration-base.php'; + require_once $base_path . '/includes/commands/class-mu-migration-export.php'; + require_once $base_path . '/includes/commands/class-mu-migration-import.php'; + require_once $base_path . '/includes/commands/class-mu-migration-posts.php'; + require_once $base_path . '/includes/commands/class-mu-migration-users.php'; + } + } + + /** + * Returns true if all the requirements are met. + * + * @since 2.5.0 + * @return bool + */ + public function is_loaded(): bool { + + return $this->loaded; + } +} diff --git a/inc/site-exporter/database/class-import.php b/inc/site-exporter/database/class-import.php new file mode 100644 index 00000000..86b32f07 --- /dev/null +++ b/inc/site-exporter/database/class-import.php @@ -0,0 +1,235 @@ +filename = $filename; + $this->username = $username; + $this->password = $password; + $this->database = $database; + $this->host = $host; + $this->forceDropTables = $forceDropTables; + + // Connect to the database + $this->connect(); + + // If dropTables is true then delete the tables + if ($dropTables === true) { + $this->dropTables($site_id); + } + + // Open file and import the sql + $this->openfile(); + } + + /** + * Connect to the database + * + * @return void + */ + private function connect(): void { + + try { + $this->db = new PDO('mysql:host=' . $this->host . ';dbname=' . $this->database, $this->username, $this->password); + $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + } catch (PDOException $e) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo 'Cannot connect: ' . $e->getMessage() . "\n"; + } + } + + /** + * Run queries + * + * @param string $query The query to perform. + * @return \PDOStatement|false + */ + private function query(string $query) { + + try { + return $this->db->query($query); + } catch (Error $e) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo 'Error with query: ' . $e->getMessage() . "\n"; + return false; + } + } + + /** + * Select all tables, loop through and delete/drop them. + * + * @param int|bool $site_id The site ID. + * @return void + */ + private function dropTables($site_id = false): void { + + global $wpdb; + + if (! $site_id) { + return; + } + + $table = is_multisite() ? $wpdb->base_prefix . $site_id : $wpdb->base_prefix; + + // Get list of tables + $tables = $this->query("SHOW TABLES LIKE'" . $table . "%'"); + if ($tables !== null && $tables !== false) { + // Loop through tables + $results = $tables->fetchAll(PDO::FETCH_COLUMN); + foreach ($results as $table) { + if (strpos($table, 'user') !== false) { + continue; + } + + if ($this->forceDropTables === true) { + // Delete table with foreign key checks disabled + $this->query('SET FOREIGN_KEY_CHECKS=0; DROP TABLE `' . $table . '`; SET FOREIGN_KEY_CHECKS=1;'); + } else { + // Delete table + $this->query('DROP TABLE `' . $table . '`'); + } + } + } + } + + /** + * Open $filename, loop through and import the commands + * + * @return void + */ + private function openfile(): void { + + try { + // If file cannot be found throw error + if (! file_exists($this->filename)) { + throw new Exception("Error: File not found.\n"); + } + + // Read in entire file + $fp = fopen($this->filename, 'r'); + + // Temporary variable, used to store current query + $templine = ''; + + // Loop through each line + while (($line = fgets($fp)) !== false) { + // Skip it if it's a comment + if (substr($line, 0, 2) === '--' || $line === '') { + continue; + } + + // Add this line to the current segment + $templine .= $line; + + // If it has a semicolon at the end, it's the end of the query + if (substr(trim($line), -1, 1) === ';') { + $this->query($templine); + // Reset temp variable to empty + $templine = ''; + } + } + + // Close the file + fclose($fp); + } catch (Exception $e) { + // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + echo 'Error importing: ' . $e->getMessage() . "\n"; + } + } +} diff --git a/inc/site-exporter/database/class-manager.php b/inc/site-exporter/database/class-manager.php new file mode 100644 index 00000000..e023f7d0 --- /dev/null +++ b/inc/site-exporter/database/class-manager.php @@ -0,0 +1,200 @@ +wpdb = $wpdb; + } + + /** + * Returns an array of tables in the database. + * + * If multisite && mainsite: all tables of the site + * If multisite && subsite: all tables of current blog + * If single site: all tables of the site + * + * @param int $blog_id The blog ID. + * @return array + */ + public function get_tables(int $blog_id = 0): array { + + if (function_exists('is_multisite') && is_multisite()) { + if (is_main_site() && $blog_id === 0) { + $tables = $this->wpdb->get_col("SHOW TABLES LIKE'" . $this->wpdb->base_prefix . "%'"); + } else { + $tables = $this->wpdb->get_col( + "SHOW TABLES LIKE '" . $this->wpdb->base_prefix . absint($blog_id) . "\_%'" + ); + } + } else { + $tables = $this->wpdb->get_col("SHOW TABLES LIKE'" . $this->wpdb->base_prefix . "%'"); + } + + return $tables; + } + + /** + * Returns an array containing the size of each database table. + * + * @return array Table => Table Size in KB + */ + public function get_sizes(): array { + + $sizes = []; + $tables = $this->wpdb->get_results('SHOW TABLE STATUS', ARRAY_A); + + if (is_array($tables) && ! empty($tables)) { + foreach ($tables as $table) { + $size = round($table['Data_length'] / 1024, 2); + // Translators: %s is the value of the size in kByte. + $sizes[ $table['Name'] ] = sprintf(__('(%s KB)', 'ultimate-multisite'), $size); + } + } + + return $sizes; + } + + /** + * Returns the number of rows in a table. + * + * @param string $table The table name. + * @return int + */ + public function get_rows(string $table): int { + + $table = esc_sql($table); + + return (int) $this->wpdb->get_var("SELECT COUNT(*) FROM $table"); + } + + /** + * Gets the columns in a table. + * + * @param string $table The table to check. + * @return array 1st Element: Primary Key, 2nd Element All Columns + */ + public function get_columns(string $table): array { + + $primary_key = null; + $columns = []; + $fields = $this->wpdb->get_results('DESCRIBE ' . $table); + + if (is_array($fields)) { + foreach ($fields as $column) { + $columns[] = $column->Field; + if ('PRI' === $column->Key) { + $primary_key = $column->Field; + } + } + } + + return [$primary_key, $columns]; + } + + /** + * Get table content. + * + * @param string $table The Table Name. + * @param int $start The start row. + * @param int $end Number of Rows to be fetched. + * @return array|null + */ + public function get_table_content(string $table, int $start, int $end): ?array { + + $data = $this->wpdb->get_results("SELECT * FROM $table LIMIT $start, $end", ARRAY_A); + + return $data; + } + + /** + * Update table. + * + * @param string $table The table name. + * @param array $update_sql The update SQL parts. + * @param array $where_sql The where SQL parts. + * @return int|false + */ + public function update(string $table, array $update_sql, array $where_sql) { + + $sql = 'UPDATE ' . $table . ' SET ' . implode(', ', $update_sql) . + ' WHERE ' . implode(' AND ', array_filter($where_sql)); + + return $this->wpdb->query($sql); + } + + /** + * Get table structure. + * + * @param string $table The table name. + * @return array|object|null + */ + public function get_table_structure(string $table) { + + return $this->wpdb->get_results("DESCRIBE $table"); + } + + /** + * Returns a SQL CREATE TABLE Statement for the table provided in $table. + * + * @param string $table The Name of the table we want to create the statement for. + * @return array|object|null + */ + public function get_create_table_statement(string $table) { + + return $this->wpdb->get_results("SHOW CREATE TABLE $table", ARRAY_N); + } + + /** + * Flush table. + * + * @return void + */ + public function flush(): void { + + $this->wpdb->flush(); + } + + /** + * Get base prefix. + * + * @return string + */ + public function get_base_prefix(): string { + + return $this->wpdb->base_prefix; + } +} diff --git a/inc/site-exporter/database/class-max-execution-time.php b/inc/site-exporter/database/class-max-execution-time.php new file mode 100644 index 00000000..c8cebe44 --- /dev/null +++ b/inc/site-exporter/database/class-max-execution-time.php @@ -0,0 +1,62 @@ +store(); + } + + @set_time_limit($time); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged + } + + /** + * Restore timelimit. + * + * @return void + */ + public function restore(): void { + + $this->set($this->met); + } + + /** + * Fetch the max_execution_time from php.ini. + * + * @return void + */ + public function store(): void { + + $this->met = (int) ini_get('max_execution_time'); + } +} diff --git a/inc/site-exporter/database/class-replace.php b/inc/site-exporter/database/class-replace.php new file mode 100644 index 00000000..a02ffa19 --- /dev/null +++ b/inc/site-exporter/database/class-replace.php @@ -0,0 +1,431 @@ +dbm = $dbm; + $this->max_execution = $max_execution; + } + + /** + * The main loop for search and replace. + * + * This walks every table in the db that was selected and then + * walks every row and column replacing all occurrences of a string with another. + * We split large tables into blocks when dealing with them to save on memory consumption. + * + * @param string $search What we want to replace. + * @param string $replace What we want to replace it with. + * @param array $tables The name of the table we want to look at. + * @param string|null $csv CSV data. + * + * @return array|\WP_Error Collection of information gathered during the run. + * @throws \Throwable Whatever exception is thrown if WP_DEBUG is true. + */ + public function run_search_replace(string $search, string $replace, array $tables, ?string $csv = null) { + + if ($search === $replace && '' !== $search) { + return new \WP_Error('error', esc_html__('Search and replace pattern can\'t be the same!', 'ultimate-multisite')); + } + + $this->max_execution->set(); + + $report = [ + 'errors' => null, + 'changes' => [], + 'tables' => '0', + 'changes_count' => '0', + ]; + + foreach ((array) $tables as $table) { + // Count tables. + ++$report['tables']; + $table_report = $this->replace_values($search, $replace, $table, $csv); + // Log changes if any. + if (0 !== $table_report['change']) { + $report['changes'][ $table ] = $table_report; + $report['changes_count'] += $table_report['change']; + } + } + + $this->max_execution->restore(); + + return $report; + } + + /** + * Replace data values inside the table. + * + * @param string $search Search string. + * @param string $replace Replace string. + * @param string $table Table name. + * @param string|null $csv CSV data. + * + * @return array + * @throws \Throwable Whatever exception is thrown if WP_DEBUG is true. + */ + public function replace_values(string $search = '', string $replace = '', string $table = '', ?string $csv = null): array { + + $table_report = [ + 'table_name' => $table, + 'rows' => 0, + 'change' => 0, + 'changes' => [], + 'updates' => 0, + 'start' => microtime(), + 'end' => microtime(), + 'errors' => [], + ]; + + // Check we have a search string, bail if not. + if (empty($search) && empty($csv)) { + $table_report['errors'][] = 'Search string is empty'; + + return $table_report; + } + + // Grab table structure in order to determine which columns are used to store serialized values in it. + $table_structure = $this->dbm->get_table_structure($table); + + if (! $table_structure) { + return $table_report; + } + + $maybe_serialized = []; + foreach ($table_structure as $struct) { + // Longtext is used for meta_values as best practice in all of the automatic products. + if (0 === stripos($struct->Type, 'longtext')) { + $maybe_serialized[] = strtolower($struct->Field); + } + } + + // Split columns array in primary key string and columns array. + $columns = $this->dbm->get_columns($table); + + list($primary_key, $columns) = $columns; + + if (null === $primary_key) { + $table_report['errors'][] = "The table \"{$table}\" has no primary key. Changes will have to be made manually."; + + return $table_report; + } + + $table_report['start'] = microtime(); + + // Count the number of rows we have in the table if large we'll split into blocks + $row_count = $this->dbm->get_rows($table); + + $page_size = $this->page_size; + $pages = ceil($row_count / $page_size); + + // Prepare CSV data + if (null !== $csv) { + $csv_lines = explode("\n", $csv); + $csv_head = str_getcsv('search,replace'); + foreach ($csv_lines as $line) { + $this->csv_data[] = array_combine($csv_head, str_getcsv($line)); + } + } + + for ($page = 0; $page < $pages; $page++) { + $start = $page * $page_size; + + // Grab the content of the table + $data = $this->dbm->get_table_content($table, $start, $page_size); + + if (! $data) { + $table_report['errors'][] = 'no data in table ' . $table; + } + + foreach ($data as $row) { + ++$table_report['rows']; + + $update_sql = []; + $where_sql = []; + $update = true; + + foreach ($columns as $column) { + // Skip the GUID column per WordPress Codex. + if ($column === 'guid') { + continue; + } + + $data_to_fix = $row[ $column ]; + + if ($column === $primary_key) { + $where_sql[] = $column . ' = "' . $this->mysql_escape_mimic($data_to_fix) . '"'; + continue; + } + + // Run a search replace on the data that'll respect the serialisation. + if (is_serialized($data_to_fix, false) + && in_array(strtolower($column), $maybe_serialized, true) + ) { + // Run a search replace on the data that'll respect the serialisation. + $edited_data = $this->recursive_unserialize_replace($search, $replace, $data_to_fix); + } else { + $edited_data = str_replace($search, $replace, $data_to_fix); + } + + // Run a search replace by CSV parameters if CSV input present + if (null !== $csv) { + foreach ($this->csv_data as $entry) { + $edited_data = is_serialized($edited_data, false) ? + $this->recursive_unserialize_replace( + $entry['search'], + $entry['replace'], + $edited_data + ) : str_replace($entry['search'], $entry['replace'], $data_to_fix); + } + } + + // Something was changed. + if ($edited_data !== $data_to_fix) { + ++$table_report['change']; + + // log changes + $table_report['changes'][] = [ + 'row' => $table_report['rows'], + 'column' => $column, + 'from' => $data_to_fix, + 'to' => $edited_data, + ]; + + $update_sql[] = $column . ' = "' . $this->mysql_escape_mimic($edited_data) . '"'; + $update = true; + } + } + + // Determine what to do with updates. + if (true === $this->dry_run) { + // Don't do anything if a dry run. + continue; + } + + if ($update && ! empty($where_sql) && ! empty($update_sql)) { + // If there are changes to make, run the query. + $result = $this->dbm->update($table, $update_sql, $where_sql); + + if (! $result) { + $table_report['errors'][] = sprintf( + /* translators: $1 is the number of rows found in database */ + esc_html__('Error updating row: %d.', 'ultimate-multisite'), + $table_report['rows'] + ); + } else { + ++$table_report['updates']; + } + } + } + } + + $table_report['end'] = microtime(true); + + $this->dbm->flush(); + + return $table_report; + } + + /** + * Mimics the mysql_real_escape_string function. + * + * Adapted from a post by 'feedr' on php.net. + * + * @link http://php.net/manual/en/function.mysql-real-escape-string.php#101248 + * + * @param array|string $input The string to escape. + * @return array|string + */ + public function mysql_escape_mimic($input) { + + if (is_array($input)) { + return array_map([$this, 'mysql_escape_mimic'], $input); + } + + if (! empty($input) && is_string($input)) { + return str_replace( + ['\\', "\0", "\n", "\r", "'", '"', "\x1a"], + ['\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z'], + $input + ); + } + + return $input; + } + + /** + * Recursive unserialize replace + * + * Take a serialised array and unserialize it replacing elements as needed and + * unserializing any subordinate arrays and performing the replace on those too. + * + * @param string $from String we're looking to replace. + * @param string $to What we want it to be replaced with. + * @param array|string|object $data Used to pass any subordinate arrays back to in. + * @param bool $serialised Does the array passed via $data need serialising. + * + * @throws \Throwable Whatever exception is thrown if WP_DEBUG is true. + * @return mixed The original array with all elements replaced as needed. + */ + public function recursive_unserialize_replace(string $from = '', string $to = '', $data = '', bool $serialised = true) { + + // Some unserialized data cannot be re-serialised eg. SimpleXMLElements. + try { + $unserialized = is_serialized($data, false) ? maybe_unserialize($data) : false; + + if ($unserialized !== false && ! is_serialized_string($data)) { + $data = $this->recursive_unserialize_replace($from, $to, $unserialized, false); + } elseif (is_array($data)) { + $_tmp = []; + foreach ((array) $data as $key => $value) { + $_tmp[ $key ] = $this->recursive_unserialize_replace($from, $to, $value, false); + } + + $data = $_tmp; + + unset($_tmp); + } elseif (is_object($data)) { + $_tmp = $data; + $props = get_object_vars($data); + foreach ($props as $key => $value) { + $_tmp->$key = $this->recursive_unserialize_replace($from, $to, $value, false); + } + + $data = $_tmp; + + unset($_tmp); + } else { + // Don't process data that isn't a string. + if (! is_string($data)) { + return $data; + } + + $marker = false; + + if (is_serialized_string($data)) { + $data = maybe_unserialize($data); + $marker = true; + } + + $tmp_data = $data; + $data = str_replace($from, $to, $data); + + // Do not allow to return valid serialized data, + // If after replacement data is_serialized then add one | to the replacement. + if (is_serialized($data, false)) { + $data = str_replace($from, '|' . $to, $tmp_data); + } + + if ($marker) { + $data = maybe_serialize($data); + } + } + + if ($serialised) { + $data = serialize($data); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_serialize + } + } catch (Exception $throwable) { + if (defined('WP_DEBUG') && WP_DEBUG) { + throw $throwable; + } + + /** + * Error action for search and replace. + * + * @param \Throwable $throwable The exception. + */ + do_action('wu_site_exporter_replace_error', $throwable); + } + + return $data; + } + + /** + * Returns true, if dry run, false if not + * + * @return bool + */ + public function get_dry_run(): bool { + + return $this->dry_run; + } + + /** + * Sets the dry run option. + * + * @param bool $state TRUE for dry run, FALSE for writing changes to DB. + * @return bool + */ + public function set_dry_run(bool $state): bool { + + $this->dry_run = $state; + + return $state; + } +} diff --git a/inc/site-exporter/mu-migration/LICENSE.txt b/inc/site-exporter/mu-migration/LICENSE.txt new file mode 100644 index 00000000..917a49d6 --- /dev/null +++ b/inc/site-exporter/mu-migration/LICENSE.txt @@ -0,0 +1,9 @@ +The MIT License (MIT) + +Copyright (c) 2016, Nícholas André, 10up Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/inc/site-exporter/mu-migration/README.md b/inc/site-exporter/mu-migration/README.md new file mode 100644 index 00000000..c7aef260 --- /dev/null +++ b/inc/site-exporter/mu-migration/README.md @@ -0,0 +1,125 @@ +# MU-Migration + +> This WP-CLI plugin makes the process of moving sites from single WordPress sites to a Multisite instance (or vice-versa) much easier. It exports everything into a zip package which can be used to automatically import it within the desired Multisite installation. + +[![Build Status](https://travis-ci.org/10up/MU-Migration.svg?branch=master)](https://travis-ci.org/10up/MU-Migration) [![Support Level](https://img.shields.io/badge/support-stable-blue.svg)](#support-level) [![MIT License](https://img.shields.io/github/license/10up/MU-Migration.svg)](https://github.com/10up/MU-Migration/blob/master/LICENSE.md) + +## Install + +### Requirements + +- PHP >= 7.1 +- WP-CLI >= 0.23 + +### Via WP-CLI Package Manager (requires wp-cli >= 0.23) + +Just run `wp package install 10up/mu-migration`. + +If you run into memory issues when installing the package, it's a known WP-CLI issue. [Check this out for a workaround](https://make.wordpress.org/cli/handbook/common-issues/#php-fatal-error-allowed-memory-size-of-999999-bytes-exhausted-tried-to-allocate-99-bytes). + +### Installing as a plugin + +Clone this repo onto `plugins/` folder, run `composer install` to fetch dependencies and activate the plugin. + +You need to install this on both the site you're moving and the target Multisite installation. + +## Why do I need this? + +Moving single WordPress sites to a Multisite environment (or the opposite) can be challenging, specially if you're moving more than one site to +Multisite. You'd need to replace tables prefix, update post_author and wc_customer_user (if WooCommerce is installed) with the new +users ID (Multisite has a shared users table, so if you're moving more than one site you can't guarantee that users will have the same IDs) and more. + +There are also a few housekeeping tasks that needs to be done to make sure that the new site will work smoothly and without losing any data. + +## How it works + +With a simple command you can export a whole site into a zip package. + +``` +$ wp mu-migration export all site.zip --plugins --themes --uploads +``` + +The above command will export users, tables, plugins folder, themes folder and the uploads folder to a unique zip file that you can +move to the Multisite server in order to be imported with the `import all` command. The optional flags `--plugins --themes --uploads`, +add the plugins folder, themes folder and uploads folder to the zip file respectively. + +You can also export subsites from another multisite instance, to do so pass the `--blog_id` parameter. E.g: + +``` +$ wp mu-migration export all subsite.zip --blog_id=2 +``` + +The following command can be used to import a site from a zip package. + +``` +$ wp mu-migration import all site.zip +``` + +If importing into Multisite, it will create a new site within your Multisite network based on the site you have just exported, if importing into a single install, it will override your single install with the exported subsite. + +The `import all` command will take care +of everything that needs to be done when moving a site to Multisite (replacing tables prefix, updating post_author IDs and etc). + +If you need to set up a new url for the site you're importing (if importing into staging or local environments for example), +you can pass it to the `import all` command. + +``` +$ wp mu-migration import all site.zip --new_url=multisite.dev/site +``` + +The import command also supports a `--mysql-single-transaction` parameter that will wrap the sql export into a single transaction to commit +all changes from the import at one time preventing the write from overwhelming the database server, especially in clustered mysql enviroments. + +You can also pass `--blog_id` to the `import all` command, in that case the import will override an existing subsite. + +``` +$ wp mu-migration import all site.zip --new_url=multisite.dev/site --blog_id=3 +``` + +In some edge cases it's possible that MU-Migration won't be able to recognize all custom tables while doing the export of a subsite in multisite +so if you need to move non-default tables, you can use `--tables` or `--non-default-tables` param. E.g + +``` +$ wp mu-migration export all subsite.zip --blog_id=1 --non-default-tables=wp_my_custom_table,wp_my_custom_table_2 +``` + +If you pass `--tables` it will export only the tables you have passed. So if you use it make sure to pass all tables that you want +to be exported, including the default tables. + +After the migration you can also manage users password (reset passwords and/or force users to reset their passwords). + +``` +$ wp mu-migration update_passwords [] [--blog_id=] [--reset] [--send_email] [--include=] [--exclude=] +``` + +E.g + +The following command will update all users passwords of the site with ID 3 to `new_weak_password`. + +``` +$ wp mu-migration update_passwords 'new_weak_password' --blog_id=3 +``` + +This next command will reset all users passwords to a random secure password and it will send a reset email to all users. + +``` +$ wp mu-migration update_passwords --reset --blog_id=3 --send_email +``` + +## Notes + +If your theme and plugins have been done in the WordPress way, you should not have major problem after the migration, keep in mind +that some themes may experience incompatibilities issue if doing things in the wrong way. (E.g hardcoded links like '/contact' etc) +Depending of the codebase of the site you're migrating you may need to push some fixes to your code. + +## Support Level + +**Stable:** 10up is not planning to develop any new features for this, but will still respond to bug reports and security concerns. We welcome PRs, but any that include new features should be small and easy to integrate and should not include breaking changes. We otherwise intend to keep this tested up to the most recent version of WordPress. + +## Credits + +Created by Nícholas André ([@nicholas_io](https://profiles.wordpress.org/nicholas_io)), at [10up.com](http://10up.com). + +## Like what you see? + + diff --git a/inc/site-exporter/mu-migration/bin/install-package-tests.sh b/inc/site-exporter/mu-migration/bin/install-package-tests.sh new file mode 100644 index 00000000..2ff49dd8 --- /dev/null +++ b/inc/site-exporter/mu-migration/bin/install-package-tests.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -ex + +install_db() { + mysql -e 'CREATE DATABASE IF NOT EXISTS wp_cli_test;' -uroot + mysql -e 'GRANT ALL PRIVILEGES ON wp_cli_test.* TO "wp_cli_test"@"localhost" IDENTIFIED BY "password1"' -uroot +} + +install_db diff --git a/inc/site-exporter/mu-migration/bin/test.sh b/inc/site-exporter/mu-migration/bin/test.sh new file mode 100644 index 00000000..65198feb --- /dev/null +++ b/inc/site-exporter/mu-migration/bin/test.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -ex + +# Run the unit tests, if they exist +if [ -f "phpunit.xml" ] || [ -f "phpunit.xml.dist" ] +then + phpunit +fi + +# Run the functional tests +BEHAT_TAGS=$(php utils/behat-tags.php) + +vendor/bin/behat --format progress $BEHAT_TAGS --strict diff --git a/inc/site-exporter/mu-migration/composer.json b/inc/site-exporter/mu-migration/composer.json new file mode 100644 index 00000000..2233fc7d --- /dev/null +++ b/inc/site-exporter/mu-migration/composer.json @@ -0,0 +1,25 @@ +{ + "name": "10up/mu-migration", + "description": "A set of WP-CLI commands to support the migration of single WordPress instances to multisite", + "type": "wp-cli-package", + "homepage": "https://github.com/10up/MU-Migration", + "support": { + "issues": "https://github.com/10up/MU-Migration/issues" + }, + "require": { + "alchemy/zippy": "0.4.8" + }, + "license": "MIT", + "authors": [ + { + "name": "Nícholas André", + "email": "nicholas@iotecnologia.com.br" + } + ], + "autoload": { + "files": [ "mu-migration.php" ] + }, + "require-dev": { + "behat/behat": "~2.5" + } +} diff --git a/inc/site-exporter/mu-migration/composer.lock b/inc/site-exporter/mu-migration/composer.lock new file mode 100644 index 00000000..e73b243e --- /dev/null +++ b/inc/site-exporter/mu-migration/composer.lock @@ -0,0 +1,1150 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "755a0b7cfc174b3e983f2153afebb0be", + "packages": [ + { + "name": "alchemy/zippy", + "version": "0.4.8", + "source": { + "type": "git", + "url": "https://github.com/alchemy-fr/Zippy.git", + "reference": "2c231a0956daa0fa1e6057d411504ff98717392e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/alchemy-fr/Zippy/zipball/2c231a0956daa0fa1e6057d411504ff98717392e", + "reference": "2c231a0956daa0fa1e6057d411504ff98717392e", + "shasum": "" + }, + "require": { + "doctrine/collections": "~1.0", + "php": ">=5.5", + "symfony/filesystem": "^2.0.5|^3.0", + "symfony/polyfill-mbstring": "^1.3", + "symfony/process": "^2.1|^3.0" + }, + "require-dev": { + "ext-zip": "*", + "guzzle/guzzle": "~3.0", + "guzzlehttp/guzzle": "^6.0", + "phpunit/phpunit": "^4.0|^5.0", + "symfony/finder": "^2.0.5|^3.0" + }, + "suggest": { + "ext-zip": "To use the ZipExtensionAdapter", + "guzzle/guzzle": "To use the GuzzleTeleporter with Guzzle 3", + "guzzlehttp/guzzle": "To use the GuzzleTeleporter with Guzzle 6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.4.x-dev" + } + }, + "autoload": { + "psr-4": { + "Alchemy\\Zippy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alchemy", + "email": "dev.team@alchemy.fr", + "homepage": "http://www.alchemy.fr/" + } + ], + "description": "Zippy, the archive manager companion", + "keywords": [ + "bzip", + "compression", + "tar", + "zip" + ], + "support": { + "issues": "https://github.com/alchemy-fr/Zippy/issues", + "source": "https://github.com/alchemy-fr/Zippy/tree/master" + }, + "time": "2017-03-03T08:42:32+00:00" + }, + { + "name": "doctrine/collections", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/collections.git", + "reference": "2b44dd4cbca8b5744327de78bafef5945c7e7b5e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/collections/zipball/2b44dd4cbca8b5744327de78bafef5945c7e7b5e", + "reference": "2b44dd4cbca8b5744327de78bafef5945c7e7b5e", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^0.5.3 || ^1", + "php": "^7.1.3 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9.0 || ^10.0", + "phpstan/phpstan": "^1.4.8", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.1.5", + "vimeo/psalm": "^4.22" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Collections\\": "lib/Doctrine/Common/Collections" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.", + "homepage": "https://www.doctrine-project.org/projects/collections.html", + "keywords": [ + "array", + "collections", + "iterators", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/collections/issues", + "source": "https://github.com/doctrine/collections/tree/1.8.0" + }, + "time": "2022-09-01T20:12:10+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", + "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpstan/phpstan": "1.4.10 || 1.10.15", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "0.18.4", + "psr/log": "^1 || ^2 || ^3", + "vimeo/psalm": "4.30.0 || 5.12.0" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/v1.1.1" + }, + "time": "2023-06-03T09:27:29+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v3.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "b2da5009d9bacbd91d83486aa1f44c793a8c380d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b2da5009d9bacbd91d83486aa1f44c793a8c380d", + "reference": "b2da5009d9bacbd91d83486aa1f44c793a8c380d", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/3.0" + }, + "time": "2016-07-20T05:43:46+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/process", + "version": "v3.4.47", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "b8648cf1d5af12a44a51d07ef9bf980921f15fca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/b8648cf1d5af12a44a51d07ef9bf980921f15fca", + "reference": "b8648cf1d5af12a44a51d07ef9bf980921f15fca", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v3.4.47" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T10:57:07+00:00" + } + ], + "packages-dev": [ + { + "name": "behat/behat", + "version": "v2.5.5", + "source": { + "type": "git", + "url": "https://github.com/Behat/Behat.git", + "reference": "c1e48826b84669c97a1efa78459aedfdcdcf2120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/Behat/zipball/c1e48826b84669c97a1efa78459aedfdcdcf2120", + "reference": "c1e48826b84669c97a1efa78459aedfdcdcf2120", + "shasum": "" + }, + "require": { + "behat/gherkin": "~2.3.0", + "php": ">=5.3.1", + "symfony/config": "~2.3", + "symfony/console": "~2.0", + "symfony/dependency-injection": "~2.0", + "symfony/event-dispatcher": "~2.0", + "symfony/finder": "~2.0", + "symfony/translation": "~2.3", + "symfony/yaml": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~3.7.19" + }, + "suggest": { + "behat/mink-extension": "for integration with Mink testing framework", + "behat/symfony2-extension": "for integration with Symfony2 web framework", + "behat/yii-extension": "for integration with Yii web framework" + }, + "bin": [ + "bin/behat" + ], + "type": "library", + "autoload": { + "psr-0": { + "Behat\\Behat": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Scenario-oriented BDD framework for PHP 5.3", + "homepage": "http://behat.org/", + "keywords": [ + "BDD", + "Behat", + "Symfony2" + ], + "support": { + "issues": "https://github.com/Behat/Behat/issues", + "source": "https://github.com/Behat/Behat/tree/v2.5.5" + }, + "time": "2015-06-01T09:37:55+00:00" + }, + { + "name": "behat/gherkin", + "version": "v2.3.5", + "source": { + "type": "git", + "url": "https://github.com/Behat/Gherkin.git", + "reference": "2b33963da5525400573560c173ab5c9c057e1852" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Behat/Gherkin/zipball/2b33963da5525400573560c173ab5c9c057e1852", + "reference": "2b33963da5525400573560c173ab5c9c057e1852", + "shasum": "" + }, + "require": { + "php": ">=5.3.1", + "symfony/finder": "~2.0" + }, + "require-dev": { + "symfony/config": "~2.0", + "symfony/translation": "~2.0", + "symfony/yaml": "~2.0" + }, + "suggest": { + "symfony/config": "If you want to use Config component to manage resources", + "symfony/translation": "If you want to use Symfony2 translations adapter", + "symfony/yaml": "If you want to parse features, represented in YAML files" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "2.2-dev" + } + }, + "autoload": { + "psr-0": { + "Behat\\Gherkin": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + } + ], + "description": "Gherkin DSL parser for PHP 5.3", + "homepage": "http://behat.org/", + "keywords": [ + "BDD", + "Behat", + "DSL", + "Symfony2", + "parser" + ], + "support": { + "issues": "https://github.com/Behat/Gherkin/issues", + "source": "https://github.com/Behat/Gherkin/tree/2.3" + }, + "time": "2013-10-15T11:22:17+00:00" + }, + { + "name": "psr/log", + "version": "1.1.4", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "time": "2021-05-03T11:20:27+00:00" + }, + { + "name": "symfony/config", + "version": "v2.8.52", + "source": { + "type": "git", + "url": "https://github.com/symfony/config.git", + "reference": "7dd5f5040dc04c118d057fb5886563963eb70011" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/config/zipball/7dd5f5040dc04c118d057fb5886563963eb70011", + "reference": "7dd5f5040dc04c118d057fb5886563963eb70011", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "symfony/filesystem": "~2.3|~3.0.0", + "symfony/polyfill-ctype": "~1.8" + }, + "require-dev": { + "symfony/yaml": "~2.7|~3.0.0" + }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Config\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Config Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/config/tree/v2.8.50" + }, + "time": "2018-11-26T09:38:12+00:00" + }, + { + "name": "symfony/console", + "version": "v2.8.52", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "cbcf4b5e233af15cd2bbd50dee1ccc9b7927dc12" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/cbcf4b5e233af15cd2bbd50dee1ccc9b7927dc12", + "reference": "cbcf4b5e233af15cd2bbd50dee1ccc9b7927dc12", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "symfony/debug": "^2.7.2|~3.0.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/event-dispatcher": "~2.1|~3.0.0", + "symfony/process": "~2.1|~3.0.0" + }, + "suggest": { + "psr/log-implementation": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/console/tree/v2.8.52" + }, + "time": "2018-11-20T15:55:20+00:00" + }, + { + "name": "symfony/debug", + "version": "v3.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/697c527acd9ea1b2d3efac34d9806bf255278b0a", + "reference": "697c527acd9ea1b2d3efac34d9806bf255278b0a", + "shasum": "" + }, + "require": { + "php": ">=5.5.9", + "psr/log": "~1.0" + }, + "conflict": { + "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" + }, + "require-dev": { + "symfony/class-loader": "~2.8|~3.0", + "symfony/http-kernel": "~2.8|~3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Debug\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Debug Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/debug/tree/3.0" + }, + "abandoned": "symfony/error-handler", + "time": "2016-07-30T07:22:48+00:00" + }, + { + "name": "symfony/dependency-injection", + "version": "v2.8.52", + "source": { + "type": "git", + "url": "https://github.com/symfony/dependency-injection.git", + "reference": "c306198fee8f872a8f5f031e6e4f6f83086992d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/c306198fee8f872a8f5f031e6e4f6f83086992d8", + "reference": "c306198fee8f872a8f5f031e6e4f6f83086992d8", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "conflict": { + "symfony/expression-language": "<2.6" + }, + "require-dev": { + "symfony/config": "~2.2|~3.0.0", + "symfony/expression-language": "~2.6|~3.0.0", + "symfony/yaml": "~2.3.42|~2.7.14|~2.8.7|~3.0.7" + }, + "suggest": { + "symfony/config": "", + "symfony/expression-language": "For using expressions in service container configuration", + "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\DependencyInjection\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DependencyInjection Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dependency-injection/tree/2.8" + }, + "time": "2019-04-16T11:33:46+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v2.8.52", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "a77e974a5fecb4398833b0709210e3d5e334ffb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a77e974a5fecb4398833b0709210e3d5e334ffb0", + "reference": "a77e974a5fecb4398833b0709210e3d5e334ffb0", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "^2.0.5|~3.0.0", + "symfony/dependency-injection": "~2.6|~3.0.0", + "symfony/expression-language": "~2.6|~3.0.0", + "symfony/stopwatch": "~2.3|~3.0.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v2.8.50" + }, + "time": "2018-11-21T14:20:20+00:00" + }, + { + "name": "symfony/finder", + "version": "v2.8.52", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "1444eac52273e345d9b95129bf914639305a9ba4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/1444eac52273e345d9b95129bf914639305a9ba4", + "reference": "1444eac52273e345d9b95129bf914639305a9ba4", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v2.8.50" + }, + "time": "2018-11-11T11:18:13+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/translation", + "version": "v2.8.52", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "fc58c2a19e56c29f5ba2736ec40d0119a0de2089" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/fc58c2a19e56c29f5ba2736ec40d0119a0de2089", + "reference": "fc58c2a19e56c29f5ba2736ec40d0119a0de2089", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/config": "<2.7" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "~2.8", + "symfony/intl": "~2.7.25|^2.8.18|~3.2.5", + "symfony/yaml": "~2.2|~3.0.0" + }, + "suggest": { + "psr/log-implementation": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Translation Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v2.8.50" + }, + "time": "2018-11-24T21:16:41+00:00" + }, + { + "name": "symfony/yaml", + "version": "v2.8.52", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "02c1859112aa779d9ab394ae4f3381911d84052b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/02c1859112aa779d9ab394ae4f3381911d84052b", + "reference": "02c1859112aa779d9ab394ae4f3381911d84052b", + "shasum": "" + }, + "require": { + "php": ">=5.3.9", + "symfony/polyfill-ctype": "~1.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/yaml/tree/v2.8.52" + }, + "time": "2018-11-11T11:18:13+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.3.0" +} diff --git a/inc/site-exporter/mu-migration/features/01-load-wp-cli.feature b/inc/site-exporter/mu-migration/features/01-load-wp-cli.feature new file mode 100644 index 00000000..035b8673 --- /dev/null +++ b/inc/site-exporter/mu-migration/features/01-load-wp-cli.feature @@ -0,0 +1,10 @@ +Feature: Test that WP-CLI loads. + + Scenario: WP-CLI loads for your tests + Given a WP install + + When I run `wp eval 'echo "Hello world.";'` + Then STDOUT should contain: + """ + Hello world. + """ diff --git a/inc/site-exporter/mu-migration/features/02-info.feature b/inc/site-exporter/mu-migration/features/02-info.feature new file mode 100644 index 00000000..aadd1422 --- /dev/null +++ b/inc/site-exporter/mu-migration/features/02-info.feature @@ -0,0 +1,12 @@ +Feature: Test an MU-Migration info command. + + Scenario: MU-Migration info works + Given a WP install + When I run `wp mu-migration info` + Then STDOUT should contain: + """ +MU-Migration version: %Yv{MU_MIGRATION_VERSION}%n + +Created by Nícholas André at 10up +Github: https://github.com/10up/MU-Migration + """ diff --git a/inc/site-exporter/mu-migration/features/03-export.feature b/inc/site-exporter/mu-migration/features/03-export.feature new file mode 100644 index 00000000..8be8d980 --- /dev/null +++ b/inc/site-exporter/mu-migration/features/03-export.feature @@ -0,0 +1,341 @@ +Feature: Test MU-Migration export commands. + + Scenario: MU-Migration is able to export the users of a single site + Given a WP install + + When I run `wp user list --format=count` + And save STDOUT as {USERS_COUNT} + + When I run `wp mu-migration export users users.csv` + Then the users.csv file should exist + Then STDOUT should be: + """ + Success: {USERS_COUNT} users have been exported + """ + + When I run `cat users.csv` + Then STDOUT should be CSV containing: + | ID | user_login | user_email | role | + | 1 | admin | admin@example.com | administrator | + + When I run `wp eval-file {SRC_DIR}/features/tests/csv_matches_user.php users.csv` + Then STDOUT should be: + """ + Success + """ + Scenario: MU-Migration is able to export users of a subsite in multisite + Given a WP multisite subdirectory install + Given I create multiple sites with dummy content + + When I run `wp user list --format=count --url=example.com/site-2` + And save STDOUT as {USERS_COUNT} + + When I run `wp mu-migration export users users-subsite.csv --blog_id=2` + Then the users-subsite.csv file should exist + Then STDOUT should be: + """ + Success: {USERS_COUNT} users have been exported + """ + + When I run `cat users-subsite.csv` + Then STDOUT should be CSV containing: + | ID | user_login | user_email | role | + | 1 | admin | admin@example.com | administrator | + + When I run `wp eval-file {SRC_DIR}/features/tests/csv_matches_user.php users-subsite.csv --url=example.com/site-2` + Then STDOUT should be: + """ + Success + """ + + Scenario: MU-Migration is able to export tables of a single site + Given a WP install + + When I run `wp db prefix` + And save STDOUT as {DB_PREFIX} + + When I run `wp mu-migration export tables tables.sql` + Then the tables.sql file should exist + Then the tables.sql file should contain: + """ + CREATE TABLE `{DB_PREFIX}posts` |AND| + CREATE TABLE `{DB_PREFIX}postmeta` |AND| + CREATE TABLE `{DB_PREFIX}terms` |AND| + CREATE TABLE `{DB_PREFIX}termmeta` |AND| + CREATE TABLE `{DB_PREFIX}options` |AND| + CREATE TABLE `{DB_PREFIX}comments` |AND| + CREATE TABLE `{DB_PREFIX}commentmeta` |AND| + CREATE TABLE `{DB_PREFIX}term_taxonomy` |AND| + CREATE TABLE `{DB_PREFIX}term_relationships` + """ + Then the tables.sql file should not contain: + """ + CREATE TABLE `{DB_PREFIX}users` |AND| + CREATE TABLE `{DB_PREFIX}usermeta` + """ + Then STDOUT should be: + """ + Success: The export is now complete + """ + + When I run `wp mu-migration export tables tables1.sql --tables={DB_PREFIX}posts` + Then the tables1.sql file should contain: + """ + CREATE TABLE `{DB_PREFIX}posts` + """ + Then the tables1.sql file should not contain: + """ + CREATE TABLE `{DB_PREFIX}postmeta` |AND| + CREATE TABLE `{DB_PREFIX}terms` |AND| + CREATE TABLE `{DB_PREFIX}termmeta` |AND| + CREATE TABLE `{DB_PREFIX}options` |AND| + CREATE TABLE `{DB_PREFIX}comments` |AND| + CREATE TABLE `{DB_PREFIX}commentmeta` |AND| + CREATE TABLE `{DB_PREFIX}term_taxonomy` |AND| + CREATE TABLE `{DB_PREFIX}term_relationships` + """ + + When I run `wp db query "CREATE TABLE {DB_PREFIX}custom_table (ID int, text longtext)"` + And I run `wp db query "CREATE TABLE custom_table_no_prefix (ID int, text longtext)"` + And I run `wp mu-migration export tables tables2.sql --non-default-tables={DB_PREFIX}custom_table,custom_table_no_prefix` + Then the tables2.sql file should contain: + """ + CREATE TABLE `{DB_PREFIX}custom_table` |AND| + CREATE TABLE `custom_table_no_prefix` |AND| + """ + Scenario: MU-Migration is able to export tables for subsites in Multisite + Given a WP multisite subdirectory install + Given I create multiple sites with dummy content + + When I run `wp db prefix --url=example.com/site-3` + And save STDOUT as {DB_PREFIX} + + When I run `wp mu-migration export tables tables-subsite.sql --blog_id=3` + Then the tables-subsite.sql file should exist + Then the tables-subsite.sql file should contain: + """ + CREATE TABLE `{DB_PREFIX}posts` |AND| + CREATE TABLE `{DB_PREFIX}postmeta` |AND| + CREATE TABLE `{DB_PREFIX}terms` |AND| + CREATE TABLE `{DB_PREFIX}termmeta` |AND| + CREATE TABLE `{DB_PREFIX}options` |AND| + CREATE TABLE `{DB_PREFIX}comments` |AND| + CREATE TABLE `{DB_PREFIX}commentmeta` |AND| + CREATE TABLE `{DB_PREFIX}term_taxonomy` |AND| + CREATE TABLE `{DB_PREFIX}term_relationships` |AND| + """ + Then the tables-subsite.sql file should not contain: + """ + CREATE TABLE `{DB_PREFIX}users` |AND| + CREATE TABLE `{DB_PREFIX}usermeta` |AND| + CREATE TABLE `{DB_PREFIX}blog_versions` |AND| + CREATE TABLE `{DB_PREFIX}blogs` |AND| + CREATE TABLE `{DB_PREFIX}site` |AND| + CREATE TABLE `{DB_PREFIX}sitemeta` |AND| + CREATE TABLE `{DB_PREFIX}registration_log` |AND| + CREATE TABLE `{DB_PREFIX}signups` + """ + Then STDOUT should be: + """ + Success: The export is now complete + """ + + When I run `wp mu-migration export tables tables-subsite1.sql --tables={DB_PREFIX}posts --blog_id=3` + Then the tables-subsite1.sql file should contain: + """ + CREATE TABLE `{DB_PREFIX}posts` + """ + Then the tables-subsite1.sql file should not contain: + """ + CREATE TABLE `{DB_PREFIX}postmeta` |AND| + CREATE TABLE `{DB_PREFIX}terms` |AND| + CREATE TABLE `{DB_PREFIX}termmeta` |AND| + CREATE TABLE `{DB_PREFIX}options` |AND| + CREATE TABLE `{DB_PREFIX}comments` |AND| + CREATE TABLE `{DB_PREFIX}commentmeta` |AND| + CREATE TABLE `{DB_PREFIX}term_taxonomy` |AND| + CREATE TABLE `{DB_PREFIX}term_relationships` + """ + When I run `wp db query "CREATE TABLE {DB_PREFIX}custom_table (ID int, text longtext)"` + And I run `wp db query "CREATE TABLE custom_table_no_prefix (ID int, text longtext)"` + And I run `wp mu-migration export tables tables-subsite2.sql --non-default-tables={DB_PREFIX}custom_table,custom_table_no_prefix` + Then the tables-subsite2.sql file should contain: + """ + CREATE TABLE `{DB_PREFIX}custom_table` |AND| + CREATE TABLE `custom_table_no_prefix` |AND| + """ + + Scenario: MU-Migration is able to export a single site into a zip package without themes,plugins and uploads + Given a WP install + + When I run `wp db prefix` + And save STDOUT as {DB_PREFIX} + And I run `wp plugin install jetpack --activate` + + When I run `wp mu-migration export all single-site.zip` + Then STDOUT should be: + """ + Exporting site meta data... + Exporting users... + Exporting tables + Zipping files.... + Success: A zip file named single-site.zip has been created + """ + + When I run `unzip single-site.zip -d temp_folder` + And I run `ls temp_folder/ | grep .csv` + And save STDOUT as {MU_CSV_FILE} + And I run `ls temp_folder/ | grep .json` + And save STDOUT as {MU_JSON_FILE} + And I run `ls temp_folder/ | grep .sql` + And save STDOUT as {MU_SQL_FILE} + Then the single-site.zip file should exist + Then the temp_folder/{MU_CSV_FILE} file should exist + Then the temp_folder/{MU_JSON_FILE} file should exist + Then the temp_folder/{MU_SQL_FILE} file should exist + Then the temp_folder/{MU_SQL_FILE} file should contain: + """ + CREATE TABLE `{DB_PREFIX}posts` |AND| + CREATE TABLE `{DB_PREFIX}postmeta` |AND| + CREATE TABLE `{DB_PREFIX}terms` |AND| + CREATE TABLE `{DB_PREFIX}termmeta` |AND| + CREATE TABLE `{DB_PREFIX}options` |AND| + CREATE TABLE `{DB_PREFIX}comments` |AND| + CREATE TABLE `{DB_PREFIX}commentmeta` |AND| + CREATE TABLE `{DB_PREFIX}term_taxonomy` |AND| + CREATE TABLE `{DB_PREFIX}term_relationships` + """ + + When I run `wp eval-file {SRC_DIR}/features/tests/csv_matches_user.php temp_folder/{MU_CSV_FILE}` + Then STDOUT should be: + """ + Success + """ + When I run `cat temp_folder/{MU_JSON_FILE}` + Then STDOUT should be JSON containing: + """ + { + "url": "http:\/\/example.com", + "name": "WP CLI Site", + "admin_email":"admin@example.com", + "site_language":"en-US", + "db_prefix": "{DB_PREFIX}", + "blog_id": 1, + "blog_plugins": ["jetpack\/jetpack.php"], + "network_plugins": [] + } + """ + Scenario: MU-Migration is able to export a single site into a zip package with themes,plugins and uploads + Given a WP install + + When I run `wp db prefix` + And save STDOUT as {DB_PREFIX} + And I run `wp plugin install jetpack --activate` + And I run `wp mu-migration export all single-site.zip --themes --plugins --uploads` + Then the single-site.zip file should exist + + When I run `unzip single-site.zip -d temp_folder` + And I run `ls temp_folder/ | grep .csv` + And save STDOUT as {MU_CSV_FILE} + And I run `ls temp_folder/ | grep .json` + And save STDOUT as {MU_JSON_FILE} + And I run `ls temp_folder/ | grep .sql` + And save STDOUT as {MU_SQL_FILE} + Then the temp_folder/{MU_CSV_FILE} file should exist + Then the temp_folder/{MU_JSON_FILE} file should exist + Then the temp_folder/{MU_SQL_FILE} file should exist + Then the temp_folder/wp-content directory should exist + Then the temp_folder/wp-content/themes directory should exist + Then the temp_folder/wp-content/plugins directory should exist + Then the temp_folder/wp-content/plugins/jetpack directory should exist + Then the temp_folder/wp-content/uploads directory should exist + + Scenario: MU-Migration is able to export a subsite without themes, plugins and uploads + Given a WP multisite subdirectory install + Given I create multiple sites with dummy content + + When I run `wp db prefix --url=example.com/site-2` + And save STDOUT as {DB_PREFIX} + And I run `wp plugin install jetpack shortcode-ui --activate --url=example.com/site-2` + + When I run `wp mu-migration export all subsite-2.zip --blog_id=2` + Then STDOUT should be: + """ + Exporting site meta data... + Exporting users... + Exporting tables + Zipping files.... + Success: A zip file named subsite-2.zip has been created + """ + + When I run `unzip subsite-2.zip -d temp_folder_subsite` + And I run `ls temp_folder_subsite/ | grep .csv` + And save STDOUT as {MU_CSV_FILE} + And I run `ls temp_folder_subsite/ | grep .json` + And save STDOUT as {MU_JSON_FILE} + And I run `ls temp_folder_subsite/ | grep .sql` + And save STDOUT as {MU_SQL_FILE} + Then the subsite-2.zip file should exist + Then the temp_folder_subsite/{MU_CSV_FILE} file should exist + Then the temp_folder_subsite/{MU_JSON_FILE} file should exist + Then the temp_folder_subsite/{MU_SQL_FILE} file should exist + Then the temp_folder_subsite/{MU_SQL_FILE} file should contain: + """ + CREATE TABLE `{DB_PREFIX}posts` |AND| + CREATE TABLE `{DB_PREFIX}postmeta` |AND| + CREATE TABLE `{DB_PREFIX}terms` |AND| + CREATE TABLE `{DB_PREFIX}termmeta` |AND| + CREATE TABLE `{DB_PREFIX}options` |AND| + CREATE TABLE `{DB_PREFIX}comments` |AND| + CREATE TABLE `{DB_PREFIX}commentmeta` |AND| + CREATE TABLE `{DB_PREFIX}term_taxonomy` |AND| + CREATE TABLE `{DB_PREFIX}term_relationships` + """ + + When I run `wp eval-file {SRC_DIR}/features/tests/csv_matches_user.php temp_folder_subsite/{MU_CSV_FILE} --url=example.com/site-2` + Then STDOUT should be: + """ + Success + """ + When I run `cat temp_folder_subsite/{MU_JSON_FILE}` + Then STDOUT should be JSON containing: + """ + { + "url": "http:\/\/example.com/site-2", + "name": "Site 2", + "admin_email":"admin@example.com", + "site_language":"en-US", + "db_prefix": "{DB_PREFIX}", + "blog_id": 2, + "blog_plugins": ["jetpack\/jetpack.php", "shortcode-ui\/shortcode-ui.php"], + "network_plugins": [] + } + """ + Scenario: MU-Migration is able to export a subsite into a zip package with themes,plugins and uploads + Given a WP multisite subdirectory install + Given I create multiple sites with dummy content + + When I run `wp db prefix` + And save STDOUT as {DB_PREFIX} + And I run `wp plugin install jetpack --activate --url=example.com/site-2` + And I run `wp media import {SRC_DIR}/features/data/images/*.jpg --url=example.com/site-2` + And I run `wp mu-migration export all subsite-2.zip --themes --plugins --uploads` + Then the subsite-2.zip file should exist + + When I run `unzip subsite-2.zip -d temp_folder_subsite` + And I run `ls temp_folder_subsite/ | grep .csv` + And save STDOUT as {MU_CSV_FILE} + And I run `ls temp_folder_subsite/ | grep .json` + And save STDOUT as {MU_JSON_FILE} + And I run `ls temp_folder_subsite/ | grep .sql` + And save STDOUT as {MU_SQL_FILE} + Then the temp_folder_subsite/{MU_CSV_FILE} file should exist + Then the temp_folder_subsite/{MU_JSON_FILE} file should exist + Then the temp_folder_subsite/{MU_SQL_FILE} file should exist + Then the temp_folder_subsite/wp-content directory should exist + Then the temp_folder_subsite/wp-content/themes directory should exist + Then the temp_folder_subsite/wp-content/plugins directory should exist + Then the temp_folder_subsite/wp-content/plugins/jetpack directory should exist + Then the temp_folder_subsite/wp-content/uploads directory should exist + Then the temp_folder_subsite/wp-content/uploads/sites/2 directory should exist + diff --git a/inc/site-exporter/mu-migration/features/04-import.feature b/inc/site-exporter/mu-migration/features/04-import.feature new file mode 100644 index 00000000..e703a94a --- /dev/null +++ b/inc/site-exporter/mu-migration/features/04-import.feature @@ -0,0 +1,189 @@ +Feature: Test MU-Migration import commands. + + Scenario: MU-Migration is able to import the users from a single site into a subsite + Given a WP multisite subdirectory install + Given I create multiple sites with dummy content + Given a WP install in 'singlesite/' + + When I run `wp user generate --count=100 --path=singlesite` + And I run `wp user list --format=count --path=singlesite` + And save STDOUT as {SINGLE_SITE_USERS_COUNT} + And I run `wp mu-migration export users users.csv --path=singlesite` + Then the users.csv file should exist + Then STDOUT should be: + """ + Success: {SINGLE_SITE_USERS_COUNT} users have been exported + """ + When I run `wp user list --format=count --url=example.com/site-2` + Then STDOUT should be: + """ + 11 + """ + When I run `wp mu-migration import users users.csv --blog_id=2 --map_file=users-mapping.json` + Then STDOUT should contain: + """ + Parsing users.csv... + Success: A map file has been created: users-mapping.json + Success: 90 users have been imported and 11 users already existed + """ + Then the users-mapping.json file should exist + When I run `wp eval-file {SRC_DIR}/features/tests/csv_matches_user.php users.csv users-mapping.json --url=example.com/site-2` + Then STDOUT should be: + """ + Success + """ + Scenario: MU-Migration is able to import the users from a subsite into a single site + Given a WP multisite subdirectory install + Given I create multiple sites with dummy content + Given a WP install in 'singlesite/' + + When I run `wp user list --format=count --blog_id=2` + And save STDOUT as {SUBSITE_USERS_COUNT} + And I run `wp mu-migration export users users.csv --blog_id=2` + Then the users.csv file should exist + Then STDOUT should be: + """ + Success: {SUBSITE_USERS_COUNT} users have been exported + """ + When I run `wp user list --format=count --path=singlesite` + Then STDOUT should be: + """ + 1 + """ + When I run `wp mu-migration import users users.csv --path=singlesite --map_file=users-mapping.json` + Then STDOUT should contain: + """ + Parsing users.csv... + Success: A map file has been created: users-mapping.json + Success: 10 users have been imported and 1 users already existed + """ + Then the users-mapping.json file should exist + When I run `wp eval-file {SRC_DIR}/features/tests/csv_matches_user.php users.csv users-mapping.json --path=singlesite` + Then STDOUT should be: + """ + Success + """ + Scenario: MU-Migration is able to import the users from a subsite into another subsite + Given a WP multisite subdirectory install + Given I create multiple sites with dummy content + + When I run `wp user list --format=count --blog_id=2` + And save STDOUT as {SUBSITE_USERS_COUNT} + And I run `wp mu-migration export users users.csv --blog_id=2` + Then the users.csv file should exist + Then STDOUT should be: + """ + Success: {SUBSITE_USERS_COUNT} users have been exported + """ + When I run `wp user list --format=count --url=example.com/site-3` + Then STDOUT should be: + """ + 11 + """ + When I run `wp mu-migration import users users.csv --blog_id=3 --map_file=users-mapping.json` + Then STDOUT should contain: + """ + Parsing users.csv... + Success: A map file has been created: users-mapping.json + Success: 0 users have been imported and 11 users already existed + """ + Then the users-mapping.json file should exist + When I run `wp eval-file {SRC_DIR}/features/tests/csv_matches_user.php users.csv users-mapping.json --url=example.com/site-3` + Then STDOUT should be: + """ + Success + """ + Scenario: MU-Migration is able to import tables from single site into a subsite + Given a WP multisite subdirectory install + Given I create multiple sites with dummy content + Given a WP install in 'singlesite/' + + When I run `wp post create --post_type=page --post_title='Test Post' --post_status=publish --post_date='2016-12-01 07:00:00' --path=singlesite` + And I run `wp mu-migration export tables tables.sql --path=singlesite` + And I run `wp db prefix --path=singlesite` + And save STDOUT as {DB_PREFIX} + And I run `wp db prefix --url=example.com/site-2` + And save STDOUT as {SUB_DB_PREFIX} + And I run `wp mu-migration import tables tables.sql --blog_id=2 --old_prefix={DB_PREFIX} --new_prefix={SUB_DB_PREFIX} --old_url=http://singlesite.com --new_url=http://example.com/site-2` + Then STDOUT should be: + """ + Database imported + Running search-replace + Search and Replace has been successfully executed + Running Search and Replace for uploads paths + Uploads paths have been successfully updated: wp-content/uploads -> wp-content/uploads/sites/2 + """ + + When I run `wp option get siteurl --url=http://example.com/site-2` + Then STDOUT should be: + """ + http://example.com/site-2 + """ + Scenario: MU-Migration is able to import tables from a subsite into another subsite + Given a WP multisite subdirectory install + Given I create multiple sites with dummy content + + When I run `wp mu-migration export tables tables.sql --blog_id=3` + And I run `wp db prefix --url=example.com/site-3` + And save STDOUT as {DB_PREFIX} + And I run `wp db prefix --url=example.com/site-2` + And save STDOUT as {SUB_DB_PREFIX} + And I run `wp mu-migration import tables tables.sql --blog_id=2 --original_blog_id=3 --old_prefix={DB_PREFIX} --new_prefix={SUB_DB_PREFIX} --old_url=http://example.com/site-3 --new_url=http://example.com/site-2` + Then STDOUT should be: + """ + Database imported + Running search-replace + Search and Replace has been successfully executed + Running Search and Replace for uploads paths + Uploads paths have been successfully updated: wp-content/uploads/sites/3 -> wp-content/uploads/sites/2 + """ + When I run `wp option get siteurl --url=http://example.com/site-2` + Then STDOUT should be: + """ + http://example.com/site-2 + """ + + When I run `wp mu-migration export tables tables.sql --blog_id=3` + And I run `wp db prefix --url=example.com/site-3` + And save STDOUT as {DB_PREFIX} + And I run `wp db prefix --url=example.com` + And save STDOUT as {SUB_DB_PREFIX} + And I run `wp mu-migration import tables tables.sql --blog_id=1 --original_blog_id=3 --old_prefix={DB_PREFIX} --new_prefix={SUB_DB_PREFIX} --old_url=http://example.com/site-3 --new_url=http://example.com` + Then STDOUT should be: + """ + Database imported + Running search-replace + Search and Replace has been successfully executed + Running Search and Replace for uploads paths + Uploads paths have been successfully updated: wp-content/uploads/sites/3 -> wp-content/uploads + """ + When I run `wp option get siteurl --url=http://example.com/` + Then STDOUT should be: + """ + http://example.com + """ + + Scenario: MU-Migration is able to import tables from a subsite into a single site + Given a WP multisite subdirectory install + Given I create multiple sites with dummy content + Given a WP install in 'singlesite/' + + When I run `wp mu-migration export tables tables.sql --blog_id=3` + And I run `wp db prefix --url=example.com/site-3` + And save STDOUT as {DB_PREFIX} + And I run `wp db prefix --path=singlesite` + And save STDOUT as {SINGLE_DB_PREFIX} + And I run `wp mu-migration import tables tables.sql --blog_id=1 --original_blog_id=3 --old_prefix={DB_PREFIX} --new_prefix={SINGLE_DB_PREFIX} --old_url=http://example.com/site-3 --new_url=http://singlesite.com --path=singlesite` + Then STDOUT should be: + """ + Database imported + Running search-replace + Search and Replace has been successfully executed + Running Search and Replace for uploads paths + Uploads paths have been successfully updated: wp-content/uploads/sites/3 -> wp-content/uploads + """ + When I run `wp option get siteurl --path=singlesite` + Then STDOUT should be: + """ + http://singlesite.com + """ \ No newline at end of file diff --git a/inc/site-exporter/mu-migration/features/05-posts.feature b/inc/site-exporter/mu-migration/features/05-posts.feature new file mode 100644 index 00000000..64ad7ac7 --- /dev/null +++ b/inc/site-exporter/mu-migration/features/05-posts.feature @@ -0,0 +1,37 @@ +Feature: Test MU-Migration posts command. + + Scenario: MU-Migration is able to import the users and tables from a single site into a subsite and update the authors + Given a WP multisite subdirectory install + Given I create multiple sites with dummy content + Given a WP install in 'singlesite/' + + When I run `wp user create ann ann@example.com --path=singlesite` + And I run `wp post generate --count=10 --post_type=post --post_author=ann --path=singlesite` + And I insert arbitrary UID postmeta data for user "ann@example.com" in site "singlesite" + And I run `wp mu-migration export users users.csv --path=singlesite` + And I run `wp mu-migration export tables tables.sql --path=singlesite` + And I run `wp mu-migration import users users.csv --blog_id=2 --map_file=users-mapping.json` + Then the users-mapping.json file should exist + + When I run `wp db prefix --path=singlesite` + And save STDOUT as {DB_PREFIX} + And I run `wp db prefix --url=example.com/site-2` + And save STDOUT as {SUB_DB_PREFIX} + And I run `wp mu-migration import tables tables.sql --blog_id=2 --old_prefix={DB_PREFIX} --new_prefix={SUB_DB_PREFIX} --old_url=http://singlesite.com --new_url=http://example.com/site-2` + And I run `wp mu-migration posts update_author users-mapping.json --blog_id=2 --uid_fields='_a_userid_field'` + Then STDOUT should not contain: + """ + records failed to update its post_author: + """ + + When I run `wp user get $(wp post get 5 --url=example.com/site-2 --field=post_author) --field=login` + Then STDOUT should be: + """ + ann + """ + + When I run `wp user get $(wp post meta get 5 --url=example.com/site-2 _a_userid_field) --field=login` + Then STDOUT should be: + """ + ann + """ diff --git a/inc/site-exporter/mu-migration/features/06-migration.feature b/inc/site-exporter/mu-migration/features/06-migration.feature new file mode 100644 index 00000000..d9186676 --- /dev/null +++ b/inc/site-exporter/mu-migration/features/06-migration.feature @@ -0,0 +1,126 @@ +Feature: MU-Migration import all command + Scenario: MU-Migration is able to export a single site into a zip package with themes,plugins and uploads and import into a Multisite Network + Given a WP multisite subdirectory install + Given I create multiple sites with dummy content + Given a WP install in 'singlesite/' + + When I run `wp theme install pixgraphy --activate --path=singlesite` + And I run `wp plugin install jetpack --activate --path=singlesite` + And I run `wp plugin install shortcode-ui --path=singlesite` + And I run `wp media import {SRC_DIR}/features/data/images/*.jpg --path=singlesite` + And I run `wp mu-migration export all single-site.zip --themes --plugins --uploads --path=singlesite` + Then the single-site.zip file should exist + + When I run `wp mu-migration import all single-site.zip --new_url=http://singlesite2.com` + And I run `wp site list --fields=blog_id,url` + Then STDOUT should be a table containing rows: + | blog_id | url | + | 4 | http://singlesite2.com/ | + + When I run `wp mu-migration import all single-site.zip --blog_id=4` + And I run `wp site list --fields=blog_id,url` + Then STDOUT should be a table containing rows: + | blog_id | url | + | 4 | http://singlesite.com/ | + + When I run `wp mu-migration import all single-site.zip --blog_id=4 --new_url=http://singlesite2.com --verbose` + Then STDOUT should contain: + """ + Uploads paths have been successfully updated: wp-content/uploads -> wp-content/uploads/sites/4 |AND| + Success: All done, your new site is available at http://singlesite2.com. Remember to flush the cache (memcache, redis etc). + """ + + When I run `wp site list --fields=blog_id,url` + Then STDOUT should be a table containing rows: + | blog_id | url | + | 4 | http://singlesite2.com/ | + + Then the wp-content/themes/pixgraphy directory should exist + Then the wp-content/plugins/jetpack directory should exist + Then the wp-content/plugins/shortcode-ui directory should not exist + + When I run `wp theme list --status=active --field=name --url=singlesite2.com` + Then STDOUT should be: + """ + pixgraphy + """ + When I run `wp plugin list --status-active --field=name --url=singlesite2.com` + Then STDOUT should contain: + """ + jetpack + """ + Scenario: MU-Migration is able to export a subsite into a zip package with themes,plugins and uploads and import into a single site + Given a WP multisite subdirectory install + Given I create multiple sites with dummy content + Given a WP install in 'singlesite/' + + When I run `wp theme install pixgraphy --activate --url=example.com/site-2` + And I run `wp plugin install jetpack --activate --url=example.com/site-2` + And I run `wp plugin install shortcode-ui --activate-network` + And I run `wp media import {SRC_DIR}/features/data/images/*.jpg --url=example.com/site-2` + And I run `wp mu-migration export all sub-site.zip --themes --plugins --uploads --blog_id=2` + Then the sub-site.zip file should exist + + When I run `wp mu-migration import all sub-site.zip --new_url=http://subsite.com --verbose --path=singlesite` + Then STDOUT should contain: + """ + Uploads paths have been successfully updated: wp-content/uploads/sites/2 -> wp-content/uploads |AND| + Success: All done, your new site is available at http://subsite.com. Remember to flush the cache (memcache, redis etc). + """ + Then the wp-content/themes/pixgraphy directory should exist + Then the wp-content/plugins/jetpack directory should exist + + When I run `wp option get siteurl --path=singlesite` + Then STDOUT should be: + """ + http://subsite.com + """ + + When I run `wp theme list --status=active --field=name --path=singlesite` + Then STDOUT should be: + """ + pixgraphy + """ + When I run `wp plugin list --status-active --field=name --path=singlesite` + Then STDOUT should contain: + """ + jetpack |AND| + shortcode-ui + """ + Scenario: MU-Migration is able to export a subsite into a zip package with themes,plugins and uploads and import into another subsite + Given a WP multisite subdirectory install + Given I create multiple sites with dummy content + + When I run `wp theme install pixgraphy --activate --url=example.com/site-2` + And I run `wp plugin install jetpack --activate --url=example.com/site-2` + And I run `wp plugin install shortcode-ui --activate-network` + And I run `wp media import {SRC_DIR}/features/data/images/*.jpg --url=example.com/site-2` + And I run `wp mu-migration export all sub-site.zip --themes --plugins --uploads --blog_id=2` + Then the sub-site.zip file should exist + + When I run `wp mu-migration import all sub-site.zip --blog_id=1 --new_url=http://example.com --verbose` + Then STDOUT should contain: + """ + Uploads paths have been successfully updated: wp-content/uploads/sites/2 -> wp-content/uploads |AND| + Success: All done, your new site is available at http://example.com. Remember to flush the cache (memcache, redis etc). + """ + Then the wp-content/themes/pixgraphy directory should exist + Then the wp-content/plugins/jetpack directory should exist + + When I run `wp option get siteurl` + Then STDOUT should be: + """ + http://example.com + """ + + When I run `wp theme list --status=active --field=name` + Then STDOUT should be: + """ + pixgraphy + """ + When I run `wp plugin list --status-active --field=name` + Then STDOUT should contain: + """ + jetpack |AND| + shortcode-ui + """ \ No newline at end of file diff --git a/inc/site-exporter/mu-migration/features/bootstrap/FeatureContext.php b/inc/site-exporter/mu-migration/features/bootstrap/FeatureContext.php new file mode 100644 index 00000000..cc1f5efe --- /dev/null +++ b/inc/site-exporter/mu-migration/features/bootstrap/FeatureContext.php @@ -0,0 +1,946 @@ +autoload->files) ) { + $contents = 'require:' . PHP_EOL; + foreach ( $composer->autoload->files as $file ) { + $contents .= ' - ' . dirname(dirname(__DIR__)) . '/' . $file . PHP_EOL; + } + @mkdir(sys_get_temp_dir() . '/wp-cli-package-test/'); + $project_config = sys_get_temp_dir() . '/wp-cli-package-test/config.yml'; + file_put_contents($project_config, $contents); + putenv('WP_CLI_CONFIG_PATH=' . $project_config); + } + } + // Inside WP-CLI +} else { + require_once __DIR__ . '/../../php/utils.php'; + require_once __DIR__ . '/../../php/WP_CLI/Process.php'; + require_once __DIR__ . '/../../php/WP_CLI/ProcessRun.php'; + if ( file_exists(__DIR__ . '/../../vendor/autoload.php') ) { + require_once __DIR__ . '/../../vendor/autoload.php'; + } elseif ( file_exists(__DIR__ . '/../../../../autoload.php') ) { + require_once __DIR__ . '/../../../../autoload.php'; + } +} + +/** + * Features context. + */ +class FeatureContext extends BehatContext implements ClosuredContextInterface { + + /** + * The current working directory for scenarios that have a "Given a WP install" or "Given an empty directory" step. Variable RUN_DIR. Lives until the end of the scenario. + */ + private static $run_dir; + + /** + * Where WordPress core is downloaded to for caching, and which is copied to RUN_DIR during a "Given a WP install" step. Lives until manually deleted. + */ + private static $cache_dir; + + /** + * The directory that holds the install cache, and which is copied to RUN_DIR during a "Given a WP install" step. Recreated on each suite run. + */ + private static $install_cache_dir; + + /** + * The directory that the WP-CLI cache (WP_CLI_CACHE_DIR, normally "$HOME/.wp-cli/cache") is set to on a "Given an empty cache" step. + * Variable SUITE_CACHE_DIR. Lives until the end of the scenario (or until another "Given an empty cache" step within the scenario). + */ + private static $suite_cache_dir; + + /** + * Where the current WP-CLI source repository is copied to for Composer-based tests with a "Given a dependency on current wp-cli" step. + * Variable COMPOSER_LOCAL_REPOSITORY. Lives until the end of the suite. + */ + private static $composer_local_repository; + + /** + * The test database settings. All but `dbname` can be set via environment variables. The database is dropped at the start of each scenario and created on a "Given a WP install" step. + */ + private static $db_settings = [ + 'dbname' => 'wp_cli_test', + 'dbuser' => 'wp_cli_test', + 'dbpass' => 'password1', + 'dbhost' => '127.0.0.1', + ]; + + /** + * Array of background process ids started by the current scenario. Used to terminate them at the end of the scenario. + */ + private $running_procs = []; + + /** + * Array of variables available as {VARIABLE_NAME}. Some are always set: CORE_CONFIG_SETTINGS, SRC_DIR, CACHE_DIR, WP_VERSION-version-latest. Some are step-dependent: + * RUN_DIR, SUITE_CACHE_DIR, COMPOSER_LOCAL_REPOSITORY, PHAR_PATH. Scenarios can define their own variables using "Given save" steps. Variables are reset for each scenario. + */ + public $variables = []; + + /** + * The current feature file and scenario line number as '.'. Used in RUN_DIR and SUITE_CACHE_DIR directory names. Set at the start of each scenario. + */ + private static $temp_dir_infix; + + /** + * Settings and variables for WP_CLI_TEST_LOG_RUN_TIMES run time logging. + */ + private static $log_run_times; // Whether to log run times - WP_CLI_TEST_LOG_RUN_TIMES env var. Set on `@BeforeScenario'. + private static $suite_start_time; // When the suite started, set on `@BeforeScenario'. + private static $output_to; // Where to output log - stdout|error_log. Set on `@BeforeSuite`. + private static $num_top_processes; // Number of processes/methods to output by longest run times. Set on `@BeforeSuite`. + private static $num_top_scenarios; // Number of scenarios to output by longest run times. Set on `@BeforeSuite`. + + private static $scenario_run_times = []; // Scenario run times (top `self::$num_top_scenarios` only). + private static $scenario_count = 0; // Scenario count, incremented on `@AfterScenario`. + private static $proc_method_run_times = []; // Array of run time info for proc methods, keyed by method name and arg, each a 2-element array containing run time and run count. + + /** + * Get the environment variables required for launched `wp` processes + */ + private static function get_process_env_variables() { + // Ensure we're using the expected `wp` binary + $bin_dir = getenv('WP_CLI_BIN_DIR') ?: realpath(__DIR__ . '/../../bin'); + $vendor_dir = realpath(__DIR__ . '/../../vendor/bin'); + $env = [ + 'PATH' => $bin_dir . ':' . $vendor_dir . ':' . getenv('PATH'), + 'BEHAT_RUN' => 1, + 'HOME' => sys_get_temp_dir() . '/wp-cli-home', + ]; + if ( $config_path = getenv('WP_CLI_CONFIG_PATH') ) { + $env['WP_CLI_CONFIG_PATH'] = $config_path; + } + if ( $term = getenv('TERM') ) { + $env['TERM'] = $term; + } + if ( $php_args = getenv('WP_CLI_PHP_ARGS') ) { + $env['WP_CLI_PHP_ARGS'] = $php_args; + } + if ( $travis_build_dir = getenv('TRAVIS_BUILD_DIR') ) { + $env['TRAVIS_BUILD_DIR'] = $travis_build_dir; + } + if ( $github_token = getenv('GITHUB_TOKEN') ) { + $env['GITHUB_TOKEN'] = $github_token; + } + return $env; + } + + /** + * We cache the results of `wp core download` to improve test performance. + * Ideally, we'd cache at the HTTP layer for more reliable tests. + */ + private static function cache_wp_files() { + $wp_version_suffix = ($wp_version = getenv('WP_VERSION')) ? "-$wp_version" : ''; + self::$cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-download-cache' . $wp_version_suffix; + + if ( is_readable(self::$cache_dir . '/wp-config-sample.php') ) { + return; + } + + $cmd = Utils\esc_cmd('wp core download --force --path=%s', self::$cache_dir); + if ( $wp_version ) { + $cmd .= Utils\esc_cmd(' --version=%s', $wp_version); + } + Process::create($cmd, null, self::get_process_env_variables())->run_check(); + } + + /** + * @BeforeSuite + */ + public static function prepare(SuiteEvent $event) { + // Test performance statistics - useful for detecting slow tests. + if ( self::$log_run_times = getenv('WP_CLI_TEST_LOG_RUN_TIMES') ) { + self::log_run_times_before_suite($event); + } + + $result = Process::create('wp cli info', null, self::get_process_env_variables())->run_check(); + echo PHP_EOL; + echo $result->stdout; + echo PHP_EOL; + self::cache_wp_files(); + $result = Process::create(Utils\esc_cmd('wp core version --path=%s', self::$cache_dir), null, self::get_process_env_variables())->run_check(); + echo 'WordPress ' . $result->stdout; + echo PHP_EOL; + + // Remove install cache if any (not setting the static var). + $wp_version_suffix = ($wp_version = getenv('WP_VERSION')) ? "-$wp_version" : ''; + $wp_version_suffix = ($wp_version = getenv('WP_VERSION')) ? "-$wp_version" : ''; + $install_cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-install-cache' . $wp_version_suffix; + if ( file_exists($install_cache_dir) ) { + self::remove_dir($install_cache_dir); + } + } + + /** + * @AfterSuite + */ + public static function afterSuite(SuiteEvent $event) { + if ( self::$composer_local_repository ) { + self::remove_dir(self::$composer_local_repository); + self::$composer_local_repository = null; + } + + if ( self::$log_run_times ) { + self::log_run_times_after_suite($event); + } + } + + /** + * @BeforeScenario + */ + public function beforeScenario($event) { + if ( self::$log_run_times ) { + self::log_run_times_before_scenario($event); + } + + $this->variables['SRC_DIR'] = realpath(__DIR__ . '/../..'); + + // Used in the names of the RUN_DIR and SUITE_CACHE_DIR directories. + self::$temp_dir_infix = null; + if ( $file = self::get_event_file($event, $line) ) { + self::$temp_dir_infix = basename($file) . '.' . $line; + } + } + + /** + * @AfterScenario + */ + public function afterScenario($event) { + + if ( self::$run_dir ) { + // remove altered WP install, unless there's an error + if ( $event->getResult() < 4 ) { + self::remove_dir(self::$run_dir); + } + self::$run_dir = null; + } + + // Remove WP-CLI package directory if any. Set to `wp package path` by package-command and scaffold-package-command features, and by cli-info.feature. + if ( isset($this->variables['PACKAGE_PATH']) ) { + self::remove_dir($this->variables['PACKAGE_PATH']); + } + + // Remove SUITE_CACHE_DIR if any. + if ( self::$suite_cache_dir ) { + self::remove_dir(self::$suite_cache_dir); + self::$suite_cache_dir = null; + } + + // Remove any background processes. + foreach ( $this->running_procs as $proc ) { + $status = proc_get_status($proc); + self::terminate_proc($status['pid']); + } + + if ( self::$log_run_times ) { + self::log_run_times_after_scenario($event); + } + } + + /** + * Terminate a process and any of its children. + */ + private static function terminate_proc($master_pid) { + + $output = `ps -o ppid,pid,command | grep $master_pid`; + + foreach ( explode(PHP_EOL, $output) as $line ) { + if ( preg_match('/^\s*(\d+)\s+(\d+)/', $line, $matches) ) { + $parent = $matches[1]; + $child = $matches[2]; + + if ( $parent == $master_pid ) { + self::terminate_proc($child); + } + } + } + + if ( ! posix_kill((int) $master_pid, 9) ) { + $errno = posix_get_last_error(); + // Ignore "No such process" error as that's what we want. + if ( 3 /*ESRCH*/ !== $errno ) { + throw new RuntimeException(posix_strerror($errno)); + } + } + } + + /** + * Create a temporary WP_CLI_CACHE_DIR. Exposed as SUITE_CACHE_DIR in "Given an empty cache" step. + */ + public static function create_cache_dir() { + if ( self::$suite_cache_dir ) { + self::remove_dir(self::$suite_cache_dir); + } + self::$suite_cache_dir = sys_get_temp_dir() . '/' . uniqid('wp-cli-test-suite-cache-' . self::$temp_dir_infix . '-', true); + mkdir(self::$suite_cache_dir); + return self::$suite_cache_dir; + } + + /** + * Initializes context. + * Every scenario gets its own context object. + * + * @param array $parameters context parameters (set them up through behat.yml) + */ + public function __construct(array $parameters) { + if ( getenv('WP_CLI_TEST_DBUSER') ) { + self::$db_settings['dbuser'] = getenv('WP_CLI_TEST_DBUSER'); + } + + if ( false !== getenv('WP_CLI_TEST_DBPASS') ) { + self::$db_settings['dbpass'] = getenv('WP_CLI_TEST_DBPASS'); + } + + if ( getenv('WP_CLI_TEST_DBHOST') ) { + self::$db_settings['dbhost'] = getenv('WP_CLI_TEST_DBHOST'); + } + + // load constants + require_once 'mu-migration.php'; + + $this->drop_db(); + $this->set_cache_dir(); + $this->variables['CORE_CONFIG_SETTINGS'] = Utils\assoc_args_to_str(self::$db_settings); + $this->variables['MU_MIGRATION_VERSION'] = TENUP_MU_MIGRATION_VERSION; + } + + public function getStepDefinitionResources() { + return glob(__DIR__ . '/../steps/*.php'); + } + + public function getHookDefinitionResources() { + return []; + } + + /** + * Replace {VARIABLE_NAME}. Note that variable names can only contain uppercase letters and underscores (no numbers). + */ + public function replace_variables($str) { + $ret = preg_replace_callback('/\{([A-Z_]+)\}/', [$this, '_replace_var'], $str); + if ( false !== strpos($str, '{WP_VERSION-') ) { + $ret = $this->_replace_wp_versions($ret); + } + return $ret; + } + + /** + * Replace variables callback. + */ + private function _replace_var($matches) { + $cmd = $matches[0]; + + foreach ( array_slice($matches, 1) as $key ) { + $cmd = str_replace('{' . $key . '}', $this->variables[ $key ], $cmd); + } + + return $cmd; + } + + /** + * Substitute "{WP_VERSION-version-latest}" variables. + */ + private function _replace_wp_versions($str) { + static $wp_versions = null; + if ( null === $wp_versions ) { + $wp_versions = []; + + $response = Requests::get('https://api.wordpress.org/core/version-check/1.7/', null, ['timeout' => 30]); + if ( 200 === $response->status_code && ($body = json_decode($response->body)) && is_object($body) && isset($body->offers) && is_array($body->offers) ) { + // Latest version alias. + $wp_versions['{WP_VERSION-latest}'] = count($body->offers) ? $body->offers[0]->version : ''; + foreach ( $body->offers as $offer ) { + $sub_ver = preg_replace('/(^[0-9]+\.[0-9]+)\.[0-9]+$/', '$1', $offer->version); + $sub_ver_key = "{WP_VERSION-{$sub_ver}-latest}"; + + $main_ver = preg_replace('/(^[0-9]+)\.[0-9]+$/', '$1', $sub_ver); + $main_ver_key = "{WP_VERSION-{$main_ver}-latest}"; + + if ( ! isset($wp_versions[ $main_ver_key ]) ) { + $wp_versions[ $main_ver_key ] = $offer->version; + } + if ( ! isset($wp_versions[ $sub_ver_key ]) ) { + $wp_versions[ $sub_ver_key ] = $offer->version; + } + } + } + } + return strtr($str, $wp_versions); + } + + /** + * Get the file and line number for the current behat event. + */ + private static function get_event_file($event, &$line) { + if ( method_exists($event, 'getScenario') ) { + $scenario_feature = $event->getScenario(); + } elseif ( method_exists($event, 'getFeature') ) { + $scenario_feature = $event->getFeature(); + } elseif ( method_exists($event, 'getOutline') ) { + $scenario_feature = $event->getOutline(); + } else { + return null; + } + $line = $scenario_feature->getLine(); + return $scenario_feature->getFile(); + } + + /** + * Create the RUN_DIR directory, unless already set for this scenario. + */ + public function create_run_dir() { + if ( ! isset($this->variables['RUN_DIR']) ) { + self::$run_dir = $this->variables['RUN_DIR'] = sys_get_temp_dir() . '/' . uniqid('wp-cli-test-run-' . self::$temp_dir_infix . '-', true); + mkdir($this->variables['RUN_DIR']); + } + } + + public function build_phar($version = 'same') { + $this->variables['PHAR_PATH'] = $this->variables['RUN_DIR'] . '/' . uniqid('wp-cli-build-', true) . '.phar'; + + // Test running against a package installed as a WP-CLI dependency + // WP-CLI installed as a project dependency + $make_phar_path = __DIR__ . '/../../../../../utils/make-phar.php'; + if ( ! file_exists($make_phar_path) ) { + // Test running against WP-CLI proper + $make_phar_path = __DIR__ . '/../../utils/make-phar.php'; + if ( ! file_exists($make_phar_path) ) { + // WP-CLI as a dependency of this project + $make_phar_path = __DIR__ . '/../../vendor/wp-cli/wp-cli/utils/make-phar.php'; + } + } + + $this->proc( + Utils\esc_cmd( + 'php -dphar.readonly=0 %1$s %2$s --version=%3$s && chmod +x %2$s', + $make_phar_path, + $this->variables['PHAR_PATH'], + $version + ) + )->run_check(); + } + + public function download_phar($version = 'same') { + if ( 'same' === $version ) { + $version = WP_CLI_VERSION; + } + + $download_url = sprintf( + 'https://github.com/wp-cli/wp-cli/releases/download/v%1$s/wp-cli-%1$s.phar', + $version + ); + + $this->variables['PHAR_PATH'] = $this->variables['RUN_DIR'] . '/' + . uniqid('wp-cli-download-', true) + . '.phar'; + + Process::create( + Utils\esc_cmd( + 'curl -sSfL %1$s > %2$s && chmod +x %2$s', + $download_url, + $this->variables['PHAR_PATH'] + ) + )->run_check(); + } + + /** + * CACHE_DIR is a cache for downloaded test data such as images. Lives until manually deleted. + */ + private function set_cache_dir() { + $path = sys_get_temp_dir() . '/wp-cli-test-cache'; + if ( ! file_exists($path) ) { + mkdir($path); + } + $this->variables['CACHE_DIR'] = $path; + } + + /** + * Run a MySQL command with `$db_settings`. + * + * @param string $sql_cmd Command to run. + * @param array $assoc_args Optional. Associative array of options. Default empty. + * @param bool $add_database Optional. Whether to add dbname to the $sql_cmd. Default false. + */ + private static function run_sql($sql_cmd, $assoc_args = [], $add_database = false) { + $default_assoc_args = [ + 'host' => self::$db_settings['dbhost'], + 'user' => self::$db_settings['dbuser'], + 'pass' => self::$db_settings['dbpass'], + ]; + if ( $add_database ) { + $sql_cmd .= ' ' . escapeshellarg(self::$db_settings['dbname']); + } + $start_time = microtime(true); + Utils\run_mysql_command($sql_cmd, array_merge($assoc_args, $default_assoc_args)); + if ( self::$log_run_times ) { + self::log_proc_method_run_time('run_sql ' . $sql_cmd, $start_time); + } + } + + public function create_db() { + $dbname = self::$db_settings['dbname']; + self::run_sql('mysql --no-defaults', ['execute' => "CREATE DATABASE IF NOT EXISTS $dbname"]); + } + + public function drop_db() { + $dbname = self::$db_settings['dbname']; + self::run_sql('mysql --no-defaults', ['execute' => "DROP DATABASE IF EXISTS $dbname"]); + } + + public function proc($command, $assoc_args = [], $path = '') { + if ( ! empty($assoc_args) ) { + $command .= Utils\assoc_args_to_str($assoc_args); + } + + $env = self::get_process_env_variables(); + if ( isset($this->variables['SUITE_CACHE_DIR']) ) { + $env['WP_CLI_CACHE_DIR'] = $this->variables['SUITE_CACHE_DIR']; + } + + if ( isset($this->variables['RUN_DIR']) ) { + $cwd = "{$this->variables['RUN_DIR']}/{$path}"; + } else { + $cwd = null; + } + + return Process::create($command, $cwd, $env); + } + + /** + * Start a background process. Will automatically be closed when the tests finish. + */ + public function background_proc($cmd) { + $descriptors = [ + 0 => STDIN, + 1 => ['pipe', 'w'], + 2 => ['pipe', 'w'], + ]; + + $proc = proc_open($cmd, $descriptors, $pipes, $this->variables['RUN_DIR'], self::get_process_env_variables()); + + sleep(1); + + $status = proc_get_status($proc); + + if ( ! $status['running'] ) { + throw new RuntimeException(stream_get_contents($pipes[2])); + } else { + $this->running_procs[] = $proc; + } + } + + public function move_files($src, $dest) { + rename($this->variables['RUN_DIR'] . "/$src", $this->variables['RUN_DIR'] . "/$dest"); + } + + /** + * Remove a directory (recursive). + */ + public static function remove_dir($dir) { + Process::create(Utils\esc_cmd('rm -rf %s', $dir))->run_check(); + } + + /** + * Copy a directory (recursive). Destination directory must exist. + */ + public static function copy_dir($src_dir, $dest_dir) { + Process::create(Utils\esc_cmd('cp -r %s/* %s', $src_dir, $dest_dir))->run_check(); + } + + public function add_line_to_wp_config(&$wp_config_code, $line) { + $token = "/* That's all, stop editing!"; + + $wp_config_code = str_replace($token, "$line\n\n$token", $wp_config_code); + } + + public function download_wp($subdir = '') { + $dest_dir = $this->variables['RUN_DIR'] . "/$subdir"; + + if ( $subdir ) { + mkdir($dest_dir); + } + + self::copy_dir(self::$cache_dir, $dest_dir); + + // disable emailing + mkdir($dest_dir . '/wp-content/mu-plugins'); + copy(__DIR__ . '/../extra/no-mail.php', $dest_dir . '/wp-content/mu-plugins/no-mail.php'); + } + + public function create_config($subdir = '', $extra_php = false) { + $params = self::$db_settings; + + // Replaces all characters that are not alphanumeric or an underscore into an underscore. + $params['dbprefix'] = $subdir ? preg_replace('#[^a-zA-Z\_0-9]#', '_', $subdir) : 'wp_'; + + $params['skip-salts'] = true; + + if ( false !== $extra_php ) { + $params['extra-php'] = $extra_php; + } + + $config_cache_path = ''; + if ( self::$install_cache_dir ) { + $config_cache_path = self::$install_cache_dir . '/config_' . md5(implode(':', $params) . ':subdir=' . $subdir); + $run_dir = '' !== $subdir ? ($this->variables['RUN_DIR'] . "/$subdir") : $this->variables['RUN_DIR']; + } + + if ( $config_cache_path && file_exists($config_cache_path) ) { + copy($config_cache_path, $run_dir . '/wp-config.php'); + } else { + $this->proc('wp config create', $params, $subdir)->run_check(); + if ( $config_cache_path && file_exists($run_dir . '/wp-config.php') ) { + copy($run_dir . '/wp-config.php', $config_cache_path); + } + } + } + + public function install_wp($subdir = '') { + $wp_version_suffix = ($wp_version = getenv('WP_VERSION')) ? "-$wp_version" : ''; + self::$install_cache_dir = sys_get_temp_dir() . '/wp-cli-test-core-install-cache' . $wp_version_suffix; + if ( ! file_exists(self::$install_cache_dir) ) { + mkdir(self::$install_cache_dir); + } + + $subdir = $this->replace_variables($subdir); + + $this->create_db(); + $this->create_run_dir(); + $this->download_wp($subdir); + $this->create_config($subdir); + + $url = empty($subdir) ? 'http://example.com' : 'http://' . basename($subdir) . '.com'; + $install_args = [ + 'url' => $url, + 'title' => 'WP CLI Site', + 'admin_user' => 'admin', + 'admin_email' => 'admin@example.com', + 'admin_password' => 'password1', + ]; + + $install_cache_path = ''; + if ( self::$install_cache_dir ) { + $install_cache_path = self::$install_cache_dir . '/install_' . md5(implode(':', $install_args) . ':subdir=' . $subdir); + $run_dir = '' !== $subdir ? ($this->variables['RUN_DIR'] . "/$subdir") : $this->variables['RUN_DIR']; + } + + if ( $install_cache_path && file_exists($install_cache_path) ) { + self::copy_dir($install_cache_path, $run_dir); + self::run_sql('mysql --no-defaults', ['execute' => "source {$install_cache_path}.sql"], true /*add_database*/); + } else { + $this->proc('wp core install', $install_args, $subdir)->run_check(); + if ( $install_cache_path ) { + mkdir($install_cache_path); + self::dir_diff_copy($run_dir, self::$cache_dir, $install_cache_path); + self::run_sql('mysqldump --no-defaults', ['result-file' => "{$install_cache_path}.sql"], true /*add_database*/); + } + } + } + + public function install_wp_with_composer($vendor_directory = 'vendor') { + $this->create_run_dir(); + $this->create_db(); + + $yml_path = $this->variables['RUN_DIR'] . '/wp-cli.yml'; + file_put_contents($yml_path, 'path: WordPress'); + + $this->composer_command('init --name="wp-cli/composer-test" --type="project" --no-interaction'); + $this->composer_command('config vendor-dir ' . $vendor_directory); + $this->composer_command('require johnpbloch/wordpress --optimize-autoloader --no-interaction'); + + $config_extra_php = "require_once dirname(__DIR__) . '/" . $vendor_directory . "/autoload.php';"; + $this->create_config('WordPress', $config_extra_php); + + $install_args = [ + 'url' => 'http://localhost:8080', + 'title' => 'WP CLI Site with both WordPress and wp-cli as Composer dependencies', + 'admin_user' => 'admin', + 'admin_email' => 'admin@example.com', + 'admin_password' => 'password1', + ]; + + $this->proc('wp core install', $install_args)->run_check(); + } + + public function composer_add_wp_cli_local_repository() { + if ( ! self::$composer_local_repository ) { + self::$composer_local_repository = sys_get_temp_dir() . '/' . uniqid('wp-cli-composer-local-', true); + mkdir(self::$composer_local_repository); + + $env = self::get_process_env_variables(); + $src = isset($env['TRAVIS_BUILD_DIR']) ? $env['TRAVIS_BUILD_DIR'] : realpath(__DIR__ . '/../../'); + + self::copy_dir($src, self::$composer_local_repository . '/'); + self::remove_dir(self::$composer_local_repository . '/.git'); + self::remove_dir(self::$composer_local_repository . '/vendor'); + } + $dest = self::$composer_local_repository . '/'; + $this->composer_command("config repositories.wp-cli '{\"type\": \"path\", \"url\": \"$dest\", \"options\": {\"symlink\": false}}'"); + $this->variables['COMPOSER_LOCAL_REPOSITORY'] = self::$composer_local_repository; + } + + public function composer_require_current_wp_cli() { + $this->composer_add_wp_cli_local_repository(); + $this->composer_command('require wp-cli/wp-cli:dev-master --optimize-autoloader --no-interaction'); + } + + public function get_php_binary() { + if ( getenv('WP_CLI_PHP_USED') ) { + return getenv('WP_CLI_PHP_USED'); + } + + if ( getenv('WP_CLI_PHP') ) { + return getenv('WP_CLI_PHP'); + } + + if ( defined('PHP_BINARY') ) { + return PHP_BINARY; + } + + return 'php'; + } + + public function start_php_server() { + $cmd = Utils\esc_cmd( + '%s -S %s -t %s -c %s %s', + $this->get_php_binary(), + 'localhost:8080', + $this->variables['RUN_DIR'] . '/wordpress/', + get_cfg_var('cfg_file_path'), + $this->variables['RUN_DIR'] . '/vendor/wp-cli/server-command/router.php' + ); + $this->background_proc($cmd); + } + + private function composer_command($cmd) { + if ( ! isset($this->variables['COMPOSER_PATH']) ) { + $this->variables['COMPOSER_PATH'] = exec('which composer'); + } + $this->proc($this->variables['COMPOSER_PATH'] . ' ' . $cmd)->run_check(); + } + + /** + * Initialize run time logging. + */ + private static function log_run_times_before_suite($event) { + self::$suite_start_time = microtime(true); + + Process::$log_run_times = true; + + $travis = getenv('TRAVIS'); + + // Default output settings. + self::$output_to = 'stdout'; + self::$num_top_processes = $travis ? 10 : 40; + self::$num_top_scenarios = $travis ? 10 : 20; + + // Allow setting of above with "WP_CLI_TEST_LOG_RUN_TIMES=[,][,]" formatted env var. + if ( preg_match('/^(stdout|error_log)?(,[0-9]+)?(,[0-9]+)?$/i', self::$log_run_times, $matches) ) { + if ( isset($matches[1]) ) { + self::$output_to = strtolower($matches[1]); + } + if ( isset($matches[2]) ) { + self::$num_top_processes = max((int) substr($matches[2], 1), 1); + } + if ( isset($matches[3]) ) { + self::$num_top_scenarios = max((int) substr($matches[3], 1), 1); + } + } + } + + /** + * Record the start time of the scenario into the `$scenario_run_times` array. + */ + private static function log_run_times_before_scenario($event) { + if ( $scenario_key = self::get_scenario_key($event) ) { + self::$scenario_run_times[ $scenario_key ] = -microtime(true); + } + } + + /** + * Save the run time of the scenario into the `$scenario_run_times` array. Only the top `self::$num_top_scenarios` are kept. + */ + private static function log_run_times_after_scenario($event) { + if ( $scenario_key = self::get_scenario_key($event) ) { + self::$scenario_run_times[ $scenario_key ] += microtime(true); + ++self::$scenario_count; + if ( count(self::$scenario_run_times) > self::$num_top_scenarios ) { + arsort(self::$scenario_run_times); + array_pop(self::$scenario_run_times); + } + } + } + + /** + * Copy files in updated directory that are not in source directory to copy directory. ("Incremental backup".) + * Note: does not deal with changed files (ie does not compare file contents for changes), for speed reasons. + * + * @param string $upd_dir The directory to search looking for files/directories not in `$src_dir`. + * @param string $src_dir The directory to be compared to `$upd_dir`. + * @param string $cop_dir Where to copy any files/directories in `$upd_dir` but not in `$src_dir` to. + */ + private static function dir_diff_copy($upd_dir, $src_dir, $cop_dir) { + if ( false === ($files = scandir($upd_dir)) ) { + $error = error_get_last(); + throw new \RuntimeException(sprintf("Failed to open updated directory '%s': %s. " . __FILE__ . ':' . __LINE__, $upd_dir, $error['message'])); + } + foreach ( array_diff($files, ['.', '..']) as $file ) { + $upd_file = $upd_dir . '/' . $file; + $src_file = $src_dir . '/' . $file; + $cop_file = $cop_dir . '/' . $file; + if ( ! file_exists($src_file) ) { + if ( is_dir($upd_file) ) { + if ( ! file_exists($cop_file) && ! mkdir($cop_file, 0777, true /*recursive*/) ) { + $error = error_get_last(); + throw new \RuntimeException(sprintf("Failed to create copy directory '%s': %s. " . __FILE__ . ':' . __LINE__, $cop_file, $error['message'])); + } + self::copy_dir($upd_file, $cop_file); + } elseif ( ! copy($upd_file, $cop_file) ) { + $error = error_get_last(); + throw new \RuntimeException(sprintf("Failed to copy '%s' to '%s': %s. " . __FILE__ . ':' . __LINE__, $upd_file, $cop_file, $error['message'])); + } + } elseif ( is_dir($upd_file) ) { + self::dir_diff_copy($upd_file, $src_file, $cop_file); + } + } + } + + /** + * Get the scenario key used for `$scenario_run_times` array. + * Format " :", eg "core-command core-update.feature:221". + */ + private static function get_scenario_key($event) { + $scenario_key = ''; + if ( $file = self::get_event_file($event, $line) ) { + $scenario_grandparent = Utils\basename(dirname(dirname($file))); + $scenario_key = $scenario_grandparent . ' ' . Utils\basename($file) . ':' . $line; + } + return $scenario_key; + } + + /** + * Print out stats on the run times of processes and scenarios. + */ + private static function log_run_times_after_suite($event) { + + $suite = ''; + if ( self::$scenario_run_times ) { + // Grandparent directory is first part of key. + $keys = array_keys(self::$scenario_run_times); + $suite = substr($keys[0], 0, strpos($keys[0], ' ')); + } + + $run_from = Utils\basename(dirname(dirname(__DIR__))); + + // Format same as Behat, if have minutes. + $fmt = function ($time) { + $mins = floor($time / 60); + return round($time, 3) . ($mins ? (' (' . $mins . 'm' . round($time - ($mins * 60), 3) . 's)') : ''); + }; + + $time = microtime(true) - self::$suite_start_time; + + $log = PHP_EOL . str_repeat('(', 80) . PHP_EOL; + + // Process and proc method run times. + $run_times = array_merge(Process::$run_times, self::$proc_method_run_times); + + list( $ptime, $calls ) = array_reduce( + $run_times, + function ($carry, $item) { + return [$carry[0] + $item[0], $carry[1] + $item[1]]; + }, + [0, 0] + ); + + $overhead = $time - $ptime; + $pct = round(($overhead / $time) * 100); + $unique = count($run_times); + + $log .= sprintf( + PHP_EOL . "Total process run time %s (tests %s, overhead %.3f %d%%), calls %d (%d unique) for '%s' run from '%s'" . PHP_EOL, + $fmt($ptime), + $fmt($time), + $overhead, + $pct, + $calls, + $unique, + $suite, + $run_from + ); + + uasort( + $run_times, + function ($a, $b) { + return $a[0] === $b[0] ? 0 : ($a[0] < $b[0] ? 1 : -1); // Reverse sort. + } + ); + + $tops = array_slice($run_times, 0, self::$num_top_processes, true); + + $log .= PHP_EOL . 'Top ' . self::$num_top_processes . " process run times for '$suite'"; + $log .= PHP_EOL . implode( + PHP_EOL, + array_map( + function ($k, $v, $i) { + return sprintf(' %3d. %7.3f %3d %s', $i + 1, round($v[0], 3), $v[1], $k); + }, + array_keys($tops), + $tops, + array_keys(array_keys($tops)) + ) + ) . PHP_EOL; + + // Scenario run times. + arsort(self::$scenario_run_times); + + $tops = array_slice(self::$scenario_run_times, 0, self::$num_top_scenarios, true); + + $log .= PHP_EOL . 'Top ' . self::$num_top_scenarios . ' (of ' . self::$scenario_count . ") scenario run times for '$suite'"; + $log .= PHP_EOL . implode( + PHP_EOL, + array_map( + function ($k, $v, $i) { + return sprintf(' %3d. %7.3f %s', $i + 1, round($v, 3), substr($k, strpos($k, ' ') + 1)); + }, + array_keys($tops), + $tops, + array_keys(array_keys($tops)) + ) + ) . PHP_EOL; + + $log .= PHP_EOL . str_repeat(')', 80); + + if ( 'error_log' === self::$output_to ) { + error_log($log); + } else { + echo PHP_EOL . $log; + } + } + + /** + * Log the run time of a proc method (one that doesn't use Process but does (use a function that does) a `proc_open()`). + */ + private static function log_proc_method_run_time($key, $start_time) { + $run_time = microtime(true) - $start_time; + if ( ! isset(self::$proc_method_run_times[ $key ]) ) { + self::$proc_method_run_times[ $key ] = [0, 0]; + } + self::$proc_method_run_times[ $key ][0] += $run_time; + ++self::$proc_method_run_times[ $key ][1]; + } +} diff --git a/inc/site-exporter/mu-migration/features/bootstrap/Process.php b/inc/site-exporter/mu-migration/features/bootstrap/Process.php new file mode 100644 index 00000000..6777b14a --- /dev/null +++ b/inc/site-exporter/mu-migration/features/bootstrap/Process.php @@ -0,0 +1,118 @@ + STDIN, + 1 => ['pipe', 'w'], + 2 => ['pipe', 'w'], + ]; + + /** + * @var bool Whether to log run time info or not. + */ + public static $log_run_times = false; + + /** + * @var array Array of process run time info, keyed by process command, each a 2-element array containing run time and run count. + */ + public static $run_times = []; + + /** + * @param string $command Command to execute. + * @param string $cwd Directory to execute the command in. + * @param array $env Environment variables to set when running the command. + * + * @return Process + */ + public static function create($command, $cwd = null, $env = []) { + $proc = new self(); + + $proc->command = $command; + $proc->cwd = $cwd; + $proc->env = $env; + + return $proc; + } + + private function __construct() {} + + /** + * Run the command. + * + * @return ProcessRun + */ + public function run() { + $start_time = microtime(true); + + $proc = proc_open($this->command, self::$descriptors, $pipes, $this->cwd, $this->env); + + $stdout = stream_get_contents($pipes[1]); + fclose($pipes[1]); + + $stderr = stream_get_contents($pipes[2]); + fclose($pipes[2]); + + $return_code = proc_close($proc); + + $run_time = microtime(true) - $start_time; + + if ( self::$log_run_times ) { + if ( ! isset(self::$run_times[ $this->command ]) ) { + self::$run_times[ $this->command ] = [0, 0]; + } + self::$run_times[ $this->command ][0] += $run_time; + ++self::$run_times[ $this->command ][1]; + } + + return new ProcessRun( + [ + 'stdout' => $stdout, + 'stderr' => $stderr, + 'return_code' => $return_code, + 'command' => $this->command, + 'cwd' => $this->cwd, + 'env' => $this->env, + 'run_time' => $run_time, + ] + ); + } + + /** + * Run the command, but throw an Exception on error. + * + * @return ProcessRun + */ + public function run_check() { + $r = $this->run(); + + // $r->STDERR is incorrect, but kept incorrect for backwards-compat + if ( $r->return_code || ! empty($r->STDERR) ) { + throw new \RuntimeException($r); + } + + return $r; + } +} diff --git a/inc/site-exporter/mu-migration/features/bootstrap/ProcessRun.php b/inc/site-exporter/mu-migration/features/bootstrap/ProcessRun.php new file mode 100644 index 00000000..1c20e33a --- /dev/null +++ b/inc/site-exporter/mu-migration/features/bootstrap/ProcessRun.php @@ -0,0 +1,67 @@ + $value ) { + $this->$key = $value; + } + } + + /** + * Return properties of executed command as a string. + * + * @return string + */ + public function __toString() { + $out = "$ $this->command\n"; + $out .= "$this->stdout\n$this->stderr"; + $out .= "cwd: $this->cwd\n"; + $out .= "run time: $this->run_time\n"; + $out .= "exit status: $this->return_code"; + + return $out; + } +} diff --git a/inc/site-exporter/mu-migration/features/bootstrap/support.php b/inc/site-exporter/mu-migration/features/bootstrap/support.php new file mode 100644 index 00000000..59e38da3 --- /dev/null +++ b/inc/site-exporter/mu-migration/features/bootstrap/support.php @@ -0,0 +1,218 @@ + $value ) { + if ( ! compareContents($value, $actual->$name) ) { + return false; + } + } + } elseif ( is_array($expected) ) { + foreach ( $expected as $key => $value ) { + if ( ! compareContents($value, $actual[ $key ]) ) { + return false; + } + } + } else { + return $expected === $actual; + } + + return true; +} + + +/** + * Compare two strings containing JSON to ensure that @a $actualJson contains at + * least what the JSON string @a $expectedJson contains. + * + * @return whether or not @a $actualJson contains @a $expectedJson + * @retval true @a $actualJson contains @a $expectedJson + * @retval false @a $actualJson does not contain @a $expectedJson + * + * @param[in] $actualJson the JSON string to be tested + * @param[in] $expectedJson the expected JSON string + * + * Examples: + * expected: {'a':1,'array':[1,3,5]} + * + * 1 ) + * actual: {'a':1,'b':2,'c':3,'array':[1,2,3,4,5]} + * return: true + * + * 2 ) + * actual: {'b':2,'c':3,'array':[1,2,3,4,5]} + * return: false + * element 'a' is missing from the root object + * + * 3 ) + * actual: {'a':0,'b':2,'c':3,'array':[1,2,3,4,5]} + * return: false + * the value of element 'a' is not 1 + * + * 4 ) + * actual: {'a':1,'b':2,'c':3,'array':[1,2,4,5]} + * return: false + * the contents of 'array' does not include 3 + */ +function checkThatJsonStringContainsJsonString($actualJson, $expectedJson) { + $actualValue = json_decode($actualJson); + $expectedValue = json_decode($expectedJson); + + if ( ! $actualValue ) { + return false; + } + + return compareContents($expectedValue, $actualValue); +} + + +/** + * Compare two strings to confirm $actualCSV contains $expectedCSV + * Both strings are expected to have headers for their CSVs. + * $actualCSV must match all data rows in $expectedCSV + * + * @param string A CSV string + * @param array A nested array of values + * @return bool Whether $actualCSV contains $expectedCSV + */ +function checkThatCsvStringContainsValues($actualCSV, $expectedCSV) { + $actualCSV = array_map('str_getcsv', explode(PHP_EOL, $actualCSV)); + + if ( empty($actualCSV) ) { + return false; + } + + // Each sample must have headers + $actualHeaders = array_values(array_shift($actualCSV)); + $expectedHeaders = array_values(array_shift($expectedCSV)); + + // Each expectedCSV must exist somewhere in actualCSV in the proper column + $expectedResult = 0; + foreach ( $expectedCSV as $expected_row ) { + $expected_row = array_combine($expectedHeaders, $expected_row); + foreach ( $actualCSV as $actual_row ) { + if ( count($actualHeaders) != count($actual_row) ) { + continue; + } + + $actual_row = array_intersect_key(array_combine($actualHeaders, $actual_row), $expected_row); + if ( $actual_row == $expected_row ) { + ++$expectedResult; + } + } + } + + return $expectedResult >= count($expectedCSV); +} + + +/** + * Compare two strings containing YAML to ensure that @a $actualYaml contains at + * least what the YAML string @a $expectedYaml contains. + * + * @return whether or not @a $actualYaml contains @a $expectedJson + * @retval true @a $actualYaml contains @a $expectedJson + * @retval false @a $actualYaml does not contain @a $expectedJson + * + * @param[in] $actualYaml the YAML string to be tested + * @param[in] $expectedYaml the expected YAML string + */ +function checkThatYamlStringContainsYamlString($actualYaml, $expectedYaml) { + $actualValue = Mustangostang\Spyc::YAMLLoad($actualYaml); + $expectedValue = Mustangostang\Spyc::YAMLLoad($expectedYaml); + + if ( ! $actualValue ) { + return false; + } + + return compareContents($expectedValue, $actualValue); +} + + +function file_exists_regex($regex, $dir = './') { + $open = opendir($dir); + var_dump($regex); + while ( ($file = readdir($open)) !== false ) { + if ( preg_match("/$regex/", $file) ) { + return true; + } + } + return false; +} diff --git a/inc/site-exporter/mu-migration/features/bootstrap/utils.php b/inc/site-exporter/mu-migration/features/bootstrap/utils.php new file mode 100644 index 00000000..2084d053 --- /dev/null +++ b/inc/site-exporter/mu-migration/features/bootstrap/utils.php @@ -0,0 +1,1111 @@ +config) && ! empty($composer->config->{'vendor-dir'}) ) { + array_unshift($vendor_paths, WP_CLI_ROOT . '/../../../' . $composer->config->{'vendor-dir'}); + } + } + return $vendor_paths; +} + +// Using require() directly inside a class grants access to private methods to the loaded code +function load_file($path) { + require_once $path; +} + +function load_command($name) { + $path = WP_CLI_ROOT . "/php/commands/$name.php"; + + if ( is_readable($path) ) { + include_once $path; + } +} + +/** + * Like array_map(), except it returns a new iterator, instead of a modified array. + * + * Example: + * + * $arr = array('Football', 'Socker'); + * + * $it = iterator_map($arr, 'strtolower', function($val) { + * return str_replace('foo', 'bar', $val); + * }); + * + * foreach ( $it as $val ) { + * var_dump($val); + * } + * + * @param array|object Either a plain array or another iterator + * @param callback The function to apply to an element + * @return object An iterator that applies the given callback(s) + */ +function iterator_map($it, $fn) { + if ( is_array($it) ) { + $it = new \ArrayIterator($it); + } + + if ( ! method_exists($it, 'add_transform') ) { + $it = new Transform($it); + } + + foreach ( array_slice(func_get_args(), 1) as $fn ) { + $it->add_transform($fn); + } + + return $it; +} + +/** + * Search for file by walking up the directory tree until the first file is found or until $stop_check($dir) returns true + * + * @param string|array The files (or file) to search for + * @param string|null The directory to start searching from; defaults to CWD + * @param callable Function which is passed the current dir each time a directory level is traversed + * @return null|string Null if the file was not found + */ +function find_file_upward($files, $dir = null, $stop_check = null) { + $files = (array) $files; + if ( is_null($dir) ) { + $dir = getcwd(); + } + while ( @is_readable($dir) ) { + // Stop walking up when the supplied callable returns true being passed the $dir + if ( is_callable($stop_check) && call_user_func($stop_check, $dir) ) { + return null; + } + + foreach ( $files as $file ) { + $path = $dir . DIRECTORY_SEPARATOR . $file; + if ( file_exists($path) ) { + return $path; + } + } + + $parent_dir = dirname($dir); + if ( empty($parent_dir) || $parent_dir === $dir ) { + break; + } + $dir = $parent_dir; + } + return null; +} + +function is_path_absolute($path) { + // Windows + if ( isset($path[1]) && ':' === $path[1] ) { + return true; + } + + return $path[0] === '/'; +} + +/** + * Composes positional arguments into a command string. + * + * @param array + * @return string + */ +function args_to_str($args) { + return ' ' . implode(' ', array_map('escapeshellarg', $args)); +} + +/** + * Composes associative arguments into a command string. + * + * @param array + * @return string + */ +function assoc_args_to_str($assoc_args) { + $str = ''; + + foreach ( $assoc_args as $key => $value ) { + if ( true === $value ) { + $str .= " --$key"; + } elseif ( is_array($value) ) { + foreach ( $value as $_ => $v ) { + $str .= assoc_args_to_str([$key => $v]); + } + } else { + $str .= " --$key=" . escapeshellarg($value); + } + } + + return $str; +} + +/** + * Given a template string and an arbitrary number of arguments, + * returns the final command, with the parameters escaped. + */ +function esc_cmd($cmd) { + if ( func_num_args() < 2 ) { + trigger_error('esc_cmd() requires at least two arguments.', E_USER_WARNING); + } + + $args = func_get_args(); + + $cmd = array_shift($args); + + return vsprintf($cmd, array_map('escapeshellarg', $args)); +} + +function locate_wp_config() { + static $path; + + if ( null === $path ) { + if ( file_exists(ABSPATH . 'wp-config.php') ) { + $path = ABSPATH . 'wp-config.php'; + } elseif ( file_exists(ABSPATH . '../wp-config.php') && ! file_exists(ABSPATH . '/../wp-settings.php') ) { + $path = ABSPATH . '../wp-config.php'; + } else { + $path = false; + } + + if ( $path ) { + $path = realpath($path); + } + } + + return $path; +} + +function wp_version_compare($since, $operator) { + return version_compare(str_replace(['-src'], '', $GLOBALS['wp_version']), $since, $operator); +} + +/** + * Render a collection of items as an ASCII table, JSON, CSV, YAML, list of ids, or count. + * + * Given a collection of items with a consistent data structure: + * + * ``` + * $items = array( + * array( + * 'key' => 'foo', + * 'value' => 'bar', + * ) + * ); + * ``` + * + * Render `$items` as an ASCII table: + * + * ``` + * WP_CLI\Utils\format_items( 'table', $items, array( 'key', 'value' ) ); + * + * # +-----+-------+ + * # | key | value | + * # +-----+-------+ + * # | foo | bar | + * # +-----+-------+ + * ``` + * + * Or render `$items` as YAML: + * + * ``` + * WP_CLI\Utils\format_items( 'yaml', $items, array( 'key', 'value' ) ); + * + * # --- + * # - + * # key: foo + * # value: bar + * ``` + * + * @access public + * @category Output + * + * @param string $format Format to use: 'table', 'json', 'csv', 'yaml', 'ids', 'count' + * @param array $items An array of items to output. + * @param array|string $fields Named fields for each item of data. Can be array or comma-separated list. + * @return null + */ +function format_items($format, $items, $fields) { + $assoc_args = compact('format', 'fields'); + $formatter = new \WP_CLI\Formatter($assoc_args); + $formatter->display_items($items); +} + +/** + * Write data as CSV to a given file. + * + * @access public + * + * @param resource $fd File descriptor + * @param array $rows Array of rows to output + * @param array $headers List of CSV columns (optional) + */ +function write_csv($fd, $rows, $headers = []) { + if ( ! empty($headers) ) { + fputcsv($fd, $headers); + } + + foreach ( $rows as $row ) { + if ( ! empty($headers) ) { + $row = pick_fields($row, $headers); + } + + fputcsv($fd, array_values($row)); + } +} + +/** + * Pick fields from an associative array or object. + * + * @param array|object Associative array or object to pick fields from + * @param array List of fields to pick + * @return array + */ +function pick_fields($item, $fields) { + $item = (object) $item; + + $values = []; + + foreach ( $fields as $field ) { + $values[ $field ] = isset($item->$field) ? $item->$field : null; + } + + return $values; +} + +/** + * Launch system's $EDITOR for the user to edit some text. + * + * @access public + * @category Input + * + * @param string $content Some form of text to edit (e.g. post content) + * @return string|bool Edited text, if file is saved from editor; false, if no change to file. + */ +function launch_editor_for_input($input, $filename = 'WP-CLI') { + + check_proc_available('launch_editor_for_input'); + + $tmpdir = get_temp_dir(); + + do { + $tmpfile = basename($filename); + $tmpfile = preg_replace('|\.[^.]*$|', '', $tmpfile); + $tmpfile .= '-' . substr(md5(rand()), 0, 6); + $tmpfile = $tmpdir . $tmpfile . '.tmp'; + $fp = @fopen($tmpfile, 'x'); + if ( ! $fp && is_writable($tmpdir) && file_exists($tmpfile) ) { + $tmpfile = ''; + continue; + } + if ( $fp ) { + fclose($fp); + } + } while ( ! $tmpfile ); + + if ( ! $tmpfile ) { + \WP_CLI::error('Error creating temporary file.'); + } + + $output = ''; + file_put_contents($tmpfile, $input); + + $editor = getenv('EDITOR'); + if ( ! $editor ) { + if ( isset($_SERVER['OS']) && false !== strpos($_SERVER['OS'], 'indows') ) { + $editor = 'notepad'; + } else { + $editor = 'vi'; + } + } + + $descriptorspec = [STDIN, STDOUT, STDERR]; + $process = proc_open("$editor " . escapeshellarg($tmpfile), $descriptorspec, $pipes); + $r = proc_close($process); + if ( $r ) { + exit($r); + } + + $output = file_get_contents($tmpfile); + + unlink($tmpfile); + + if ( $output === $input ) { + return false; + } + + return $output; +} + +/** + * @param string MySQL host string, as defined in wp-config.php + * @return array + */ +function mysql_host_to_cli_args($raw_host) { + $assoc_args = []; + + $host_parts = explode(':', $raw_host); + if ( count($host_parts) == 2 ) { + list( $assoc_args['host'], $extra ) = $host_parts; + $extra = trim($extra); + if ( is_numeric($extra) ) { + $assoc_args['port'] = intval($extra); + $assoc_args['protocol'] = 'tcp'; + } elseif ( $extra !== '' ) { + $assoc_args['socket'] = $extra; + } + } else { + $assoc_args['host'] = $raw_host; + } + + return $assoc_args; +} + +function run_mysql_command($cmd, $assoc_args, $descriptors = null) { + check_proc_available('run_mysql_command'); + + if ( ! $descriptors ) { + $descriptors = [STDIN, STDOUT, STDERR]; + } + + if ( isset($assoc_args['host']) ) { + $assoc_args = array_merge($assoc_args, mysql_host_to_cli_args($assoc_args['host'])); + } + + $pass = $assoc_args['pass']; + unset($assoc_args['pass']); + + $old_pass = getenv('MYSQL_PWD'); + putenv('MYSQL_PWD=' . $pass); + + $final_cmd = force_env_on_nix_systems($cmd) . assoc_args_to_str($assoc_args); + + $proc = proc_open($final_cmd, $descriptors, $pipes); + if ( ! $proc ) { + exit(1); + } + + $r = proc_close($proc); + + putenv('MYSQL_PWD=' . $old_pass); + + if ( $r ) { + exit($r); + } +} + +/** + * Render PHP or other types of files using Mustache templates. + * + * IMPORTANT: Automatic HTML escaping is disabled! + */ +function mustache_render($template_name, $data = []) { + if ( ! file_exists($template_name) ) { + $template_name = WP_CLI_ROOT . "/templates/$template_name"; + } + + $template = file_get_contents($template_name); + + $m = new \Mustache_Engine( + [ + 'escape' => function ($val) { + return $val; }, + ] + ); + + return $m->render($template, $data); +} + +/** + * Create a progress bar to display percent completion of a given operation. + * + * Progress bar is written to STDOUT, and disabled when command is piped. Progress + * advances with `$progress->tick()`, and completes with `$progress->finish()`. + * Process bar also indicates elapsed time and expected total time. + * + * ``` + * # `wp user generate` ticks progress bar each time a new user is created. + * # + * # $ wp user generate --count=500 + * # Generating users 22 % [=======> ] 0:05 / 0:23 + * + * $progress = \WP_CLI\Utils\make_progress_bar( 'Generating users', $count ); + * for ( $i = 0; $i < $count; $i++ ) { + * // uses wp_insert_user() to insert the user + * $progress->tick(); + * } + * $progress->finish(); + * ``` + * + * @access public + * @category Output + * + * @param string $message Text to display before the progress bar. + * @param integer $count Total number of ticks to be performed. + * @return cli\progress\Bar|WP_CLI\NoOp + */ +function make_progress_bar($message, $count) { + if ( \cli\Shell::isPiped() ) { + return new \WP_CLI\NoOp(); + } + + return new \cli\progress\Bar($message, $count); +} + +function parse_url($url) { + $url_parts = \parse_url($url); + + if ( ! isset($url_parts['scheme']) ) { + $url_parts = parse_url('http://' . $url); + } + + return $url_parts; +} + +/** + * Check if we're running in a Windows environment (cmd.exe). + * + * @return bool + */ +function is_windows() { + return false !== ($test_is_windows = getenv('WP_CLI_TEST_IS_WINDOWS')) ? (bool) $test_is_windows : strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; +} + +/** + * Replace magic constants in some PHP source code. + * + * @param string $source The PHP code to manipulate. + * @param string $path The path to use instead of the magic constants + */ +function replace_path_consts($source, $path) { + $replacements = [ + '__FILE__' => "'$path'", + '__DIR__' => "'" . dirname($path) . "'", + ]; + + $old = array_keys($replacements); + $new = array_values($replacements); + + return str_replace($old, $new, $source); +} + +/** + * Make a HTTP request to a remote URL. + * + * Wraps the Requests HTTP library to ensure every request includes a cert. + * + * ``` + * # `wp core download` verifies the hash for a downloaded WordPress archive + * + * $md5_response = Utils\http_request( 'GET', $download_url . '.md5' ); + * if ( 20 != substr( $md5_response->status_code, 0, 2 ) ) { + * WP_CLI::error( "Couldn't access md5 hash for release (HTTP code {$response->status_code})" ); + * } + * ``` + * + * @access public + * + * @param string $method HTTP method (GET, POST, DELETE, etc.) + * @param string $url URL to make the HTTP request to. + * @param array $headers Add specific headers to the request. + * @param array $options + * @return object + */ +function http_request($method, $url, $data = null, $headers = [], $options = []) { + + $cert_path = '/rmccue/requests/library/Requests/Transport/cacert.pem'; + if ( inside_phar() ) { + // cURL can't read Phar archives + $options['verify'] = extract_from_phar( + WP_CLI_VENDOR_DIR . $cert_path + ); + } else { + foreach ( get_vendor_paths() as $vendor_path ) { + if ( file_exists($vendor_path . $cert_path) ) { + $options['verify'] = $vendor_path . $cert_path; + break; + } + } + if ( empty($options['verify']) ) { + WP_CLI::error('Cannot find SSL certificate.'); + } + } + + try { + $request = \Requests::request($url, $headers, $data, $method, $options); + return $request; + } catch ( \Requests_Exception $ex ) { + // CURLE_SSL_CACERT_BADFILE only defined for PHP >= 7. + if ( 'curlerror' !== $ex->getType() || ! in_array(curl_errno($ex->getData()), [CURLE_SSL_CONNECT_ERROR, CURLE_SSL_CERTPROBLEM, 77 /*CURLE_SSL_CACERT_BADFILE*/], true) ) { + \WP_CLI::error(sprintf("Failed to get url '%s': %s.", $url, $ex->getMessage())); + } + // Handle SSL certificate issues gracefully + \WP_CLI::warning(sprintf("Re-trying without verify after failing to get verified url '%s' %s.", $url, $ex->getMessage())); + $options['verify'] = false; + try { + return \Requests::request($url, $headers, $data, $method, $options); + } catch ( \Requests_Exception $ex ) { + \WP_CLI::error(sprintf("Failed to get non-verified url '%s' %s.", $url, $ex->getMessage())); + } + } +} + +/** + * Increments a version string using the "x.y.z-pre" format + * + * Can increment the major, minor or patch number by one + * If $new_version == "same" the version string is not changed + * If $new_version is not a known keyword, it will be used as the new version string directly + * + * @param string $current_version + * @param string $new_version + * @return string + */ +function increment_version($current_version, $new_version) { + // split version assuming the format is x.y.z-pre + $current_version = explode('-', $current_version, 2); + $current_version[0] = explode('.', $current_version[0]); + + switch ( $new_version ) { + case 'same': + // do nothing + break; + + case 'patch': + ++$current_version[0][2]; + + $current_version = [$current_version[0]]; // drop possible pre-release info + break; + + case 'minor': + ++$current_version[0][1]; + $current_version[0][2] = 0; + + $current_version = [$current_version[0]]; // drop possible pre-release info + break; + + case 'major': + ++$current_version[0][0]; + $current_version[0][1] = 0; + $current_version[0][2] = 0; + + $current_version = [$current_version[0]]; // drop possible pre-release info + break; + + default: // not a keyword + $current_version = [[$new_version]]; + break; + } + + // reconstruct version string + $current_version[0] = implode('.', $current_version[0]); + $current_version = implode('-', $current_version); + + return $current_version; +} + +/** + * Compare two version strings to get the named semantic version. + * + * @access public + * + * @param string $new_version + * @param string $original_version + * @return string $name 'major', 'minor', 'patch' + */ +function get_named_sem_ver($new_version, $original_version) { + + if ( ! Comparator::greaterThan($new_version, $original_version) ) { + return ''; + } + + $parts = explode('-', $original_version); + $bits = explode('.', $parts[0]); + $major = $bits[0]; + if ( isset($bits[1]) ) { + $minor = $bits[1]; + } + if ( isset($bits[2]) ) { + $patch = $bits[2]; + } + + if ( ! is_null($minor) && Semver::satisfies($new_version, "{$major}.{$minor}.x") ) { + return 'patch'; + } elseif ( Semver::satisfies($new_version, "{$major}.x.x") ) { + return 'minor'; + } else { + return 'major'; + } +} + +/** + * Return the flag value or, if it's not set, the $default value. + * + * Because flags can be negated (e.g. --no-quiet to negate --quiet), this + * function provides a safer alternative to using + * `isset( $assoc_args['quiet'] )` or similar. + * + * @access public + * @category Input + * + * @param array $assoc_args Arguments array. + * @param string $flag Flag to get the value. + * @param mixed $default Default value for the flag. Default: NULL + * @return mixed + */ +function get_flag_value($assoc_args, $flag, $default = null) { + return isset($assoc_args[ $flag ]) ? $assoc_args[ $flag ] : $default; +} + +/** + * Get the home directory. + * + * @access public + * @category System + * + * @return string + */ +function get_home_dir() { + $home = getenv('HOME'); + if ( ! $home ) { + // In Windows $HOME may not be defined + $home = getenv('HOMEDRIVE') . getenv('HOMEPATH'); + } + + return rtrim($home, '/\\'); +} + +/** + * Appends a trailing slash. + * + * @access public + * @category System + * + * @param string $string What to add the trailing slash to. + * @return string String with trailing slash added. + */ +function trailingslashit($string) { + return rtrim($string, '/\\') . '/'; +} + +/** + * Get the system's temp directory. Warns user if it isn't writable. + * + * @access public + * @category System + * + * @return string + */ +function get_temp_dir() { + static $temp = ''; + + if ( $temp ) { + return $temp; + } + + // `sys_get_temp_dir()` introduced PHP 5.2.1. + if ( $try = sys_get_temp_dir() ) { + $temp = trailingslashit($try); + } elseif ( $try = ini_get('upload_tmp_dir') ) { + $temp = trailingslashit($try); + } else { + $temp = '/tmp/'; + } + + if ( ! @is_writable($temp) ) { + \WP_CLI::warning("Temp directory isn't writable: {$temp}"); + } + + return $temp; +} + +/** + * Parse a SSH url for its host, port, and path. + * + * Similar to parse_url(), but adds support for defined SSH aliases. + * + * ``` + * host OR host/path/to/wordpress OR host:port/path/to/wordpress + * ``` + * + * @access public + * + * @return mixed + */ +function parse_ssh_url($url, $component = -1) { + preg_match('#^((docker|docker\-compose|ssh|vagrant):)?(([^@:]+)@)?([^:/~]+)(:([\d]*))?((/|~)(.+))?$#', $url, $matches); + $bits = []; + foreach ( [ + 2 => 'scheme', + 4 => 'user', + 5 => 'host', + 7 => 'port', + 8 => 'path', + ] as $i => $key ) { + if ( ! empty($matches[ $i ]) ) { + $bits[ $key ] = $matches[ $i ]; + } + } + switch ( $component ) { + case PHP_URL_SCHEME: + return isset($bits['scheme']) ? $bits['scheme'] : null; + case PHP_URL_USER: + return isset($bits['user']) ? $bits['user'] : null; + case PHP_URL_HOST: + return isset($bits['host']) ? $bits['host'] : null; + case PHP_URL_PATH: + return isset($bits['path']) ? $bits['path'] : null; + case PHP_URL_PORT: + return isset($bits['port']) ? $bits['port'] : null; + default: + return $bits; + } +} + +/** + * Report the results of the same operation against multiple resources. + * + * @access public + * @category Input + * + * @param string $noun Resource being affected (e.g. plugin) + * @param string $verb Type of action happening to the noun (e.g. activate) + * @param integer $total Total number of resource being affected. + * @param integer $successes Number of successful operations. + * @param integer $failures Number of failures. + */ +function report_batch_operation_results($noun, $verb, $total, $successes, $failures) { + $plural_noun = $noun . 's'; + $past_tense_verb = past_tense_verb($verb); + $past_tense_verb_upper = ucfirst($past_tense_verb); + if ( $failures ) { + if ( $successes ) { + WP_CLI::error("Only {$past_tense_verb} {$successes} of {$total} {$plural_noun}."); + } else { + WP_CLI::error("No {$plural_noun} {$past_tense_verb}."); + } + } elseif ( $successes ) { + WP_CLI::success("{$past_tense_verb_upper} {$successes} of {$total} {$plural_noun}."); + } else { + $message = $total > 1 ? ucfirst($plural_noun) : ucfirst($noun); + WP_CLI::success("{$message} already {$past_tense_verb}."); + } +} + +/** + * Parse a string of command line arguments into an $argv-esqe variable. + * + * @access public + * @category Input + * + * @param string $arguments + * @return array + */ +function parse_str_to_argv($arguments) { + preg_match_all('/(?<=^|\s)([\'"]?)(.+?)(? 'reset']; + if ( isset($irregular[ $verb ]) ) { + return $irregular[ $verb ]; + } + $last = substr($verb, -1); + if ( 'e' === $last ) { + $verb = substr($verb, 0, -1); + } elseif ( 'y' === $last && ! preg_match('/[aeiou]y$/', $verb) ) { + $verb = substr($verb, 0, -1) . 'i'; + } elseif ( preg_match('/^[^aeiou]*[aeiou][^aeiouhwxy]$/', $verb) ) { + // Rule of thumb that most (all?) one-voweled regular verbs ending in vowel + consonant (excluding "h", "w", "x", "y") double their final consonant - misses many cases (eg "submit"). + $verb .= $last; + } + return $verb . 'ed'; +} diff --git a/inc/site-exporter/mu-migration/features/data/images/beach.jpg b/inc/site-exporter/mu-migration/features/data/images/beach.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8501e583d3ed0c126a53928015ba43c26dc02617 GIT binary patch literal 227604 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
axLb` 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
    W)?e*qvfovjsr*pz`g1Ou=8FY{F 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Ð-kCp)>wcuOMch5Vm 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 literal 0 HcmV?d00001 diff --git a/inc/site-exporter/mu-migration/features/data/images/mossoro.jpg b/inc/site-exporter/mu-migration/features/data/images/mossoro.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8479fd260c894463a9b9137aad5ced416df72e44 GIT binary patch literal 155842 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 YzwGVn{{T*R{Ez+r0N~^Pj`83B*)@xI4gdfE literal 0 HcmV?d00001 diff --git a/inc/site-exporter/mu-migration/features/data/images/wp_chara.jpg b/inc/site-exporter/mu-migration/features/data/images/wp_chara.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6c3d5abf5525a27ca6cb3757b063ef5738f35443 GIT binary patch literal 95622 zcmZsCbyV9;*DYF{0)=43T?-UVfqIkV3`d%~0zrO=QGkfETU&}5{=RiU6@Nui)%fQT@VUvRK-XdoZ3PNFjE zh=_=*n@SsyuSoXN+D=eVC|Lizp=ba4yg+{Z>?{FvRwBw&h_7?cF~duWe~|wt^~90O{}DQ9rVsR?+K@(AH^m9ZDz`>&bZ1d|F-Vj|2Dt> zJ|F=d5&qu>1Hk#W!86kT+mM0k|83aS#s4;1(0?te{6CYq|C`PK%_RN*v-!W8{QqqJ zZzjY4H=D@7mHMZhgv>6YVs;a;gW_HJDi7058~%WyOZ_LV?0<*tR}jZ6i-?=$~3)NtErQ#?T+xImGgg1skhw- zc;?~wZvHqR3I5lGFo`_};cWkPqsrvBgs-R|{KQIHlmBs;cAcY0SvoWniiR35o7y@@ zh(XtTcSWDpxs|VA#nAtlt`)5xg|BdwzjF(U(l}icOKN|suA5igP z($n?Ifi>QbR~{Z7Es#dLlT3z?GaRU>s5m(}>7H6vRu&Q>1pq-bF3;AiD)IYXD~^r1z%jmHKh@;_bsYMC z_AC^ke_Xfx-QAt5tE*#+USW)arno`C(#p!p){l$t?n-_-^78USQAAqhK>rvZ`ijJg z?yjt&b_C6f*Zs)c()l#;{n6i$wkboR7T5Q-Z!`hHMY@h<>2H1wd-FI{ON0clQ-0^hwXkGBh^c3dN*| z`pk26w7?*@rlO;>i%|ltW#w_|`~KtUaSEk&?V71hL(#YUsNqRC5$c%YE~wKFoFySt z`JXkISl(o}p37@Joh<^H*|W1VKYHImE6@_U=HVu^ibtVqBIIO)1WWrj6Ir6U`O<>^qwo>2bcK${a=9Vl68N}q; zr=iN~g=oW^V%>?sq^!m@7~S0)1jbIQ4(jgSGj7*yk?{u&_x#;o`kt`=I1NhepOvW{ zKRp@}P?VofX=i8m3vM1@FHeIrQ^MmNzRzgf)?x&iKGDEdkUQuU-P+UR)@@upzmLAOaBVTK^Vrv zf1_o>oXgvb2T(O9TuxL0?qgTPn)UPVG{7>w)W7kc-bugHyG1EWP`c()Ow+n0T)b4e z8d-UFb5uN-ZNi2vLW*^X%j{=?v)?#{ouJ&^8M~Rron8Z6(rWbO=-ke>G zGd=1-#?uPN)Wr5FZ>#X?!(JjtFBatljD0YGiXOG>yt=J>PVEy?cAz0CN|494%6e*(R9CH`>&~ z0_!6n@pF`xH7sOmmHBVpn7uYX!c=}-Te(8ANuBuw0kATUUoS}Wb5&?Fy)WrpBXe4p z*Q3xUk%YoqOPV@!HaQ((fq3gnwGe9?h^LDutk*kVZ;zK0s_p6s3R@n<75u)P53HiU z&N6%DR9m)ocy(vpV(kWCmYfZ!h;gyoyeY7=t<=4qZ1O z%}~$AL61s*XfEaMcA1=s*^X9JGOC{C2}2G2i+-yqkKe6gpPmVx=#RItcSju1k6GS` zX+J*+3rtAp!&eR_V36CN-q$2^oU5}?f~#bAz!70Eg_Rp(Nh|zXb-xc)zXd4m=?-{Z zWr1EZ9>-cRC;Ps?yi@zLJuX z`}1|KhssH7G(Z!J_r+|WMXsAzCCmLhNJOi4t1g=hv{^Jg#gBuNP%wjIR{p1`>+K0; zSBjEpSmc9{D_E!Op?5sIX73A#YreHT>Tn^zg?AUZj?G7#u+v1-)Rc039gWX~rmVv8 zWx=>6nfANDj})&~#5&L3*^ku+BM<~NN-DY#pQxtrlP68hm+Z;{Rdaoz}irUoV zU$3X*Fgcg~?+ZSuxwpU;F-RD_yS>HnsJ(UyU_s1S8N#wzuIqZ!ADE||pcYs#1_b>L zV2yCv8)qdoIh>`(W#=a{$g7sEIj!@1cfTC55kLR%9Qxx9ZCw)$d{-5YYS zC;Z4cSDH(qe_1vB&Og#`i0L%FMP0e*SeW|*%%jhsRe5u90VR2XWm;NK%8$-czBk*d z7pnQk(=A4uGni;8kIp1C1GXys``^|M&)ZSbXFa*HKaF)_I~|=8Ob3Q!_eku1qgki27m1 zTJGah5!!6wkM`VLb2v?B-_2SJt0m0I5fGU55z7{I8mt98Z-z;|4CcN~&F10OU(bP` zl_Zq9#WVhVjZjXC!>zD|fVkSAi-f}KaS54{asZi?<(%#|UBrhP$6^Rlfp6X7LUlx9 z>v!BDcMN_HFv8VS-Bgh6^_X=gldUy2Hm=lfGv{|l#B03Cqr`pOZ+ONFi)(dX5^^Jn z=)B$B_Qlh)wBqi;JNjv9hmM1zF^OzAp!lHhv@_R4VieCPYs_k>`SdrRq-nZN^ZRU# z$xwTHd-F0*5_>?=Q##*zz5&G5;D`08gm=;C}N2+mH-Kh}LVXDtPWcsc?+! zS;y>(^vPjt55GhGCoX8N==SI%Fw;MrehHgf;?i!;n@SBN-xmYohOd3Qs#J5fwpQFP zg}|jI>xI#Q0k8^9On>uPd|7{D{tSG7U2Y3^Vp9_rV{I*d>P!^E-4ERO^xDSXxfvZ= zB>mQP&TfY#HZCcbwreqHCi(YN$pzbyp5dAhlqC6U%{*9Qu;SMmSJJCbMnMX`s#z%n z-d5-|97TNT4E^~Nobt)RDk(RiB64KAmz{pnTW8c;XTp0WA&K}K|3b{sqU&Jun#^hI|IQpmC1fOkgVJ*8g zUkt;d1|5kso6iUd>gQ`6ZSI%k!3Qn}(`3B7slo~JWHYuRX7k8Yr;dXQv2+`K^>lsS zPpl>t^~&j~tbQr;5&CwVELoZtoWN6^ac@}*!Jd8_xyItlS2F5`L~Cy{+#&Kv96UTk z67Ml1MmgF&^8=|^$gabci&k^WgI}GwW%48uuiI+S^h&nLX2h9+Ab_cK9@w(Wy@|At zkdU_4R+v%{E$LW{rQ_GCTw2)b&%o{{UKwecGN#zd+}`Bg$CO@?@n*^KH0>1VM4cU- zl8uU2ZS!(PwBSCrU^<)#MTbRw~2UqCMA!*#I zE_WxtAx9Mi+yw;(=awULCVy7{U5rVgQyaN!ITZBB(otH{7yFtB53B(%PYU8n4G#Fz z?F{i}Wx8~4Rn?;|^X4Ca0J)OY*liGUVfdC~QOWZAym0gR&i$GH7pTAh+S-E|TkP}bW&f1GSsV~uTqp2pYoMNS;^hwB z$t(8*+;3BDzumLmy~FBD;6|_Rr&65J)nxsS7#s@bB4 z0-VYcdVfCeiVZxU$s4lB`T@Yj)yfw3&(0<#A<5$RxN`UO+%mjLdU}4QC=H|h@p!ch zNu+p<`w_?GxqaW-bIh3_xHmv zt~ZRz!okLdaPPouDC@h)$Pb0guq19C9_TIzJkx2k<*{39mrG)vQ6t3BKu=)S585rN zNK&Nihc|vbEK_`)bMEpl)DIfO2rpZ#&<*hdq1KbpI61BX7D{c%=>^qs#>Q@nN6ViA zem;38$0amJQ9)~3#*99G>iV0M@DmD%Z*$C2Xp2dmCA57q96Z62SM5o+Crp3>1S*u) zJtwX{el{m7Z-#&|F(N3QCXJ{O_$&c#d*|~tB4u#t;JEQXYq%J5H+NJ*bu~-(;*`)k zYH;2@AARX(%2PpL|A;d0Evm#B%ij^};D9F(zMfRn=MtR;`pHvn!iduOf)6>lH(7y9 z+o!$p=q68#pvD_hV#S%HuZ-nM)eahFa1k$y(hi-eR_xtJ1K4Qh5go!>J0ZqHo~^8X zyfuEeTOSKW`JY2A4anXk)W`^UDqapIO8jo`PIbL6p6*UjDn+|xzG>uTzbS?kWHce# zlGSR|7)#{8(^;vg>>^q@IMTRiRZ+R3vRH-^H>pNrVI1+92>*C_aCo{oEIzJoYFaX_ zB1P8xO>h0{+IJ#KFz|T%R)Y ziB!le|G3zI7Qj(e(XOqJcQ|RW*M0I1suI?>UV@zbhm4|eGdL#@ICS>%`PFgnR<>_$1F9z+>a&mIg(!yX0A=3fNU*U14qf~L*c9U-mI`~S{n2pV~ zOz|E$TzLNM&J94GQZ*Ira&{L=qi}6a1_z}zPw}GpG-1dA+l^;#a3UM2SzH36t`Tia zUBEKbxtOCYz;_%oplx(3kAv}1zTLcuWsCU1f->$`_h3yBAkS6?P$**J<&!qdyk7lnT2@#i}Dc_1EH=A~R&wQO1Q z2No|n-R0v2mVPj<&0m^Yk)djOG}s8O8{{urTe!C8Tg**v!a?DAmGXT$dctKsuTQ_z zhajAs8EQ_4G!xdhH=409A0|JE{U7+s2XC&<&O6_89%Y2Z)j*A%c};XO!D#;jgeMy>9`fuBIQ1Jf7rPyC(FH%odi9o_2^8L{gkn*eG!jv!L9ArNY$*< zu&`Ft!=HO$IPZ0EW&Un!8j&TBZAzh`ZNV)*U!jYeED;y1uAca*A4|h{m#{`Y`d$SE z=x#yK$yPqCC=L}drWEwd=8N`~Oe>aS%CU%VeSH${83{Pl7sey-=iqr~Qrxu=<6bNl zUyoa~MJ8#9_07OKyhd3LHV+LMn3(&KL@@hThviJ}0fzdV&@T}!Qer8ktZ90*(kO%Z zous%A{`3lE4o@?VuZ16|)$65zaw0m$xVkxW1lAXQ=kzA3+Zf_R*8ko!BwvJ~hhifr}`N0OmN<$0i0j`)at?0m9l`F zs;5M&c}48HJ^6hNq4sVfWhBg8@vY+-70?NE?JY1Qs{atBSWU=}0j&~&Ym&? z7yY6?2?m7-UA~aX9qiFw*Z>738)WQ0vQ)(NPXZ~M=DK`+k%8ubKNX{iOk)XL;jL2A z^T@x2Nfq;`LgXVgUlv}Pd`qKsGplSB;=RKn>VuNO2ejj@Al8rP%${rcx#R(He|iED zKAIj}?T$gXLiV014n`A|R<>WDfIvd^Gb~~2$PEJCq5>pnn>L9#9PKt=V+5gVyX#om z{uh$%(?pKHz{u_JKbTcd&$vC*e^&?L+{=)R$;z%F$AEG-TXc+UpB@3~xw;9%5Eb0@ zgJh9+X6;Eb{)}w>FLPT)<%-zA5L_E5BMN)nZCvx7Fg&pKFy5>hO#%l>6F%ewX4ELf zE)3Wb40o=Kc~r0Vsnn_>eggkIWwM|h%yl;7pUB|DT{2+~9awPiYGE-U0NPz=JNGDd z=zcPLCQhPd#2Mv(TmyQ2uw$-Mfz||KTuZWjCa6S9$Dv>MtT*Zl#;zV0)55ElpAE2v z(PC@Kh(qa>kon44P|0V<<2-OnyqM8ZpsXqvpq;zI=wp;vRdwzM4O`BFqaXn<;PcY# zus!%kn&Aw#R|r0^l_iPjcTkL*PDIJTr<%cC! z*}XCws@)@h*Y;N)*y?J~txWrTiw(7H&4)!cWc|~#u}+>Ym&>xkqoz`G{Dp4u?>^{f zd3R@j<)Fv%J?~DmAs8YQ6ZSp{BSAOeRG{Q{X%`b(g?QPTQk$~F6gArJkxiX_t*|%x zTE1K&W6r)Zy-i+Of4{h(j+HB7W6zv&*K+3%ukBsz>H8u>T9m3>fk5i%7AFXK5QK%| z*loYZkC?^1`ju#uaJJ@k6tB>fHje9K8;DkeDf4iKe+UY&_y)fvPDbzwvbF=Z23!KG zi@LqX{(>K+`m!bYqt3(k_JtiB9I&h9J&S&&r;isgXsl>5OObi3%`PYyj$~$N*o+?e z8SlbTUHpn9I~!-2yEvH1yJ43#qjJ_LluwbLk)`xj#ke8jcfaTh`S>$jyH&jI;&Zqr zHQ=IEI+i@B=D~rHB{7c3X4rWOV==Xfy4nux!Ds5x!bS!yf9lACR2|yHH!|vgr_&wc z!7>oztkD*_>`|r$`z>w04V=A_p$8W`qFoJwhG+aVgF{{L>C1;2lt8_+o!z8qE6eMJ zcO6oR0!AV9DW>wL>-*v#qK|KL{G!M`vIcTSfJm7%4jb2}8!PKw;e?1=$flW}SBERW z>j+Yk1p@I_#3Nf{ljr`}-1C|VGP))jk0S>m`7z6*%o_3k(2*7ApHV4eooH5Fb6}lPFSLEkK&}UnC5jGN~y_G@v z^w#E-uopI{9s8KZTt73tzpXAPfK$pbW_gV6&2D1n0Oc67!Qvx%-H+=k-vd#WY>J3` zXQKgDvkNnQx*KU!j8AOE>O;+5&p#UWS3#kz|8Aq!yM6ki4K0>`4M2*+6d14Uh%r#41Te`N;B znS(9GO!jkq4b_D(K6546pNB961e78aAz#l2uajy+0%RTcb(E{()?%N8{JUYfU$>m`gU?h&g(M zfW7?v7gJMh6V6AL4;bBMpyP6gvw?A5C|F?N+u8VtU9E(c<*IWdZoGjJE=NVqF*VLO z%?HL}wZqYK=JjtIi_}KIMbRbyggsxr-fLTAOj+v)IOy-jcZQ-kih9pz} zxRq;dPH-d{8IydSB-+OPy07nMFTAH_!6^JnixW+2pu~x39#na*fq{u^0)b(x^J-`) zt&)<3DpVG}Iaxe7^vi6N^STb93CFjUc;AJMq>j7>CPQL#bNXvb>%IO9d*rl>D`!m& z#LF3IvG^gM1PTZdVO;>1pt{VHJnik3D`RBl%v6<9%MDv=NC!US#G?YIa?~u{T`uXiQ zA=oUHE%?O`KrIo^sO@;NTr(6+QnZ9sn$8gUNrSKx*~Q6gvGcWvS%27bu4a2P7;RNt z+?|Je_-lmu=2t9ye2>d5iB_))*xN1>8y#- zc4|&Qz6P=8kXEo4kqTsu0?!C*(;I~J5F~A)W#1Z*fKA)qn+B)iM&EIk++7tm+6nJCf2w&F>Ts1}O4gR6m$op#@|8OozWQr^D7Ic1N0i6}of zcuKj)Ato5_hYLGI_WF2+BLz6F6R@O-L{yoO-|=kU&=7|n1Brf>78i%hVR%FRJg-ky zY?9)NO7IEHx0lwSWb(CCD{FVZs6bry>(NssJAUeCn-Ylyi#o@t&I$|q?U z7#Jv{P_JDGGr-UPnGDW-1e-w;ZB|s(m!mC`p1WSjTwS$I=3Lb|kS^D*~X}z$Z z;B>hL_RYthDR&Z6{WtD+sQEnv!k}R59EMs!=d*S`o|fk5=(}FVcHcN^1o?#e!lO_Mp{%0U;E$Hg@;B1-jxPa)CL;0RvDJm+5yPY;N=Ar!$zBQ@KR` zfqq)U62r+F{I>eFwJdd$XV@&~Ml>hE400GkPvVU*(G0 zk|br5!yOVvd^bvx&o8S)ez8VTOg%Ap^6+jbYe-7u$HFa8Y0yDHbalffnLuU462&eQ z+StPr76z#~YZuQEsI+q*t;-B5tI243d-I8Bv&j`@lYDI?yIx}1J7r8PoBr%aH%WC>Hj)JsY22GK zc3j)Q>ej^OV-Pug{);2<<>h(`65NF?@w+*6FYrNuT8)CSmkNnl)jF+P09TlHnVwWg z%Em&3Xr*Q)&+t54fRKWT4(m=v8huE0v3<7M^u^lHUI4=AydThI%0^%a@^k zqEy4v)IrEK!w%1c%-xcFQ9}Xb>U=+(&COV)Z0Z=Pv-RS9qZ26#r$)*3BAna8sg9uB zVP|KEAOO3%HjQp0Rj_%MVcA6!kAG~`0r@(|MEACb{&u&?SZdB}$U4#xbLl&&e4`$$ zSasX-XL9$k;bAH&mKn3iXuSvb?yyeDp9BX8IhU~Xog1kUePVi$`suZ{bSSZ(#9}_1 zSvvNis6r$-_cO%7WqfXDpnNQP<$_3w@gdAHe>12*+;+CL$n{%`WA8O_(2qHcrzq@+ zQ(07BVZXx?AcjkX)&(_(#(yysY~r*^fvH|B*A9HLS>XRXK%)HpT$#J2V!;t-P%G(# zbA_QD(OA8k8i7lxi=3(;l4_Xj%@IrDlBz8Vx#~Bnk}C>&U;&^QWg9(K)wH7l(aQmj zTA!0mL9XbTz-8&{+k-XmQ;%E#`d3Jx;;>0{M^4OzD$|swE4g-^-&dXjr5R#_(~=FYO-YzvKgG6p!Z0rA?v!s zS;C_~*V0{^Hf=T;4MO=J(vD!|aveheDt7e^<_EKlRtDFOUt=9813I<(ZI_x?N_--T zQ6AnclOo=xFm$(Y}`cP>^t%8&;RV``Cby;Nra6bEisyQ0Bc@heOv=7!o`C&Lmn2#urRj63Hniy!=%?UQ4D*kMBO-p5fI zmtz<=W5~p4L5F!^pJ*JvQ|UQku&8{KZ^bc(MOpkFwXV++uk5e{MZwYmJ$A8s$M7bb zT2mum6?XCCHk#=efQ{V6ynJF)L5Q=1hGd>Y*()nqs8*tpK(CR{6jW^gUSu_A3j@y5H1XHV!s2#;Wml+;JC zt6xH+)TAiP(Wz+n_hNsukhP5m8+=Xnn@BLDH+>N8^PSLXzZT$PO2; zP=3LldnxmDa%%#*^+Y-kq>4xfE0wWC$XS+lQj|pCHXI|`)NLGM;NUbk?#l8?%#`kI zZj!;5<9+$UN^^T!mdo({bnVruA5kCgSieY-iQ_8(y-P8JSEY~B2A1*d1)}u}0jME(&X*;hsvV@Lc7n66&kR=5@E*X33bZ z<5c^DOtf@Hmme2t!+lxZF$-=6bnYe4RUTI_vj*Kz0I3<-O=S@MM0`!T6m2IqG=QZz zy{ilFm(Pm|8Ys5GJ|`+NK{ea2Fx3t2D9jjEx_ak!ti?J-j&`@jhrmqYBmry8;!20)v z^!nP-(0Y1`xeNHWr12LKbao{mwy`>SJ&dtuup~KQXelE~icSTpvIAOXvve5p09-Sb z+yQq`dm|*BAG=M7465ROqC)a?$YIoT_$TX`rtbIv3>01%`_nFn=H5`)Jd66uEl>&3$-%PLba6%7FGKjxm%CK$sZU1CY@p+SYhZVr=f`o+Ba;^xLrS~C%)K2V8aJORtty`tF z%J5nECIa7=DnrfBKj=9_DjzcMw2P#u3aT!eW>AYqGV!*ImJ4OWo(^HPL1B0*ve0t4 z4c}HZu{(Qla2Hb(`v5p0Z%|t^swF>%6Upb?pd?KEFL53yVCq0)B`<%!{Xia~nfPOC zHNywWrJtmXyI#eM?PLVu4V2J`Iw z+23bK4hZ>(knO3julKm#V**w~!A?R-WWJD-{rUcUZr&9g%a-855Bv^O4T#DHnuyrE zagEZ=d&{{+8jhJgqUAvWCZ+uS{d0S`L!(F$P02w1l%T>2`&cx-p5jkE^kyuQbN$pz zehDI4p>aJSe_>DtFzmMPQFFh`-vnI{D71K!WNu)pN}oPs+srAAsN(yciMr@eqo*R_ zsx7Q-4?yzdP+D7&yAb-MBS=+BHAw|Zb7)w)MkFxG51f#hNoVq!@Czo(tsxQ|x&l$p zLCQ>A&Ii-HE=Sq$2rmB8y4wzV(PjiecAH3+^TI-miZ%lgxOOwS1CYG`{&W?AF>k}n zpI)b)cHI*DU1DHrUJ%=c(NbS~%H0d`vy=?l2!u$X1DWM!`MznhlnATDfBK!B2UZ3b z)@L`rBbt&XL9*jYSbeZ&xkXJQ_9&v}2cd=3S{>U@T~CaEsxe}F15Uld&Ba}(v|_qQ zJ`4O{X&{iWvR49!0JIJVc(}8L5hB5)&>h4(vI5=@%BSh+isaq1s+*N1l*eUN^i=aA2Y1^zFpv}Lki;YbiXEQsdk!=+|vF5@C!}I<$wwk5qQb<@zyWgcV`=+ zDOIuH)TjNFk1{fZq$zW(vMrx*?7TgQ*5G%m5lj9XhVd_+jlEuaq7gXwmnDFveOpaU zZEkK3ay&k5_91wpCd)P0EbXmtZg(Za&gEoEz)G#y5B4QwfW7(u>fn`0IbG_B8ZQb% z%cWs(4w15`_)M39BB_8)d1v%|7HYw6@1^6PmseIOJT?x3%xF+oF!?^nCySitd)fO# zsw_+x)ymaV-~(*m!rTe1_p)`}9QSn&QWCA@s4pz$A>Jsyp52MLp%aOA$9^4%gT2Zb z`faW=WunY;5b#{U0fZ`F%axg8F&?G|9S#D+QV|aE5}HCOWOhdre4h?!u;r#HdTy+L z*HSqkZYd5n$K;i+7^`ew@h+&qjrYFmz=DkK8td}hFY2nQzI^Cb?w&1%NYBEq108u< z_Zf36l)W_C1|jQ313EE1UB5k0Y^!YXkl*Z}Nr8TS+A* zInT-T6&*0co#KP7h@bo#`6eQsu<<;4-wcCdPBV=+cOvJLjBF&AkJxgaD}>p3K|V;1 zONm{ODflDR0M9XQGE;y7o)Mu%4;8o~Kv3HQv`FLV`y-YjgDI!18~{s51Gk(`Ea;s~ z{IPJp+aER~BjeEz9NbV_lNdqJ*M|69Mz0MI`ulhE!JX}eh3n1qp${VS41-COgv?>o zdQXo*BT)un{^=N9f!6F-Djy;X+@xvp0i9bCpQDq3RV4#{uRNcJ57um^=`A5wQHc}k z-Jeh@Rc3y+^|POUpR}5Da(kAwnOpCiXKip|~xY{;}|CM7WMkY^uE#f%!tC zPSk#v<@ zt(DQ?X3C~VOepzC%%6=Aj8yM_X}nv)4O^{z{3&zEQ6*0`;9ScO#@t27$?_#zxn(Ob^+`%B;8N%m_CUi>Kp=^0F{1n(^Z} z-<3l^GKuLnjzPa(WJ2u;9=~D&H04Am*7AlWxA zZStTP!Emr)ySvDjk1b-M*JbeKUvl&6bOQ^V49WgT!D5U|%d78D!@3c&9Mq~Y+LHC! z0;3#TI<_!%2guzhJ=Jh8Rr+si>RD$AkxWoF?YX$P&e(!{?I}H5Yu*xD^&Uvhjl&R1 zc;OPq;end7*UPo&X&pEXPrZ?;Fo~Y}&GtPD3mSuVo%OLsD;d9`%jBz&w0X&Dnevz` zYc!4+|FpjE#U&X>y~~NJ z*h3A79YZn&yb1x;yykTg%B|E2v%SDFn?*_@uy<~)nsR(Z1rxPW($#fY0+(GJ47^}; zH~}^;SFZczWr3U$gVuM^!`Z$F+;c)glx##&4&V?pWO^SR4c27Q$em2a*3+sC`#e`N+#0Qlzsneak_fUb`aAA;fcI?I9#+Fti`ssjbun5YH(`{1kJjM z(8T3~U~TUC8KKoGL!nf5_FuVqc@mny<`~~4g`$gu!#bC4x>!HGMJV8Vx#^I2I24MO zzuu=^4i?bu(Sn@1A6V8}4lg>-1`{`5D*&ldChpweSTszl{u7qEWeJ&g1 z9C`y4F|<8xBfC8XrN-Y;wXU%*wQXJ-yCB5+f3G}_FU4C6$$Qzok7Nlx{qM&*T#Dl+t?O|YTv=D5uoO|-=7^e9t_jmHb_(C{&h5SuJOx>V1mzMQUrqQxI&_hw$eH6L;Qh3R0ac z09n5EhJ3EKV8FCynF;#HcW&4Dxc5)VYqnTo*?(3$2$A%VhhFM=)`+xTWeJj3Msr#R zp_;TuM>8O8A43+=Mww;>L^>kl*^Q@My+VUiqlXVDaT>xADDz7Yn#L~PJT(7FCt99t zf2Y*Xf9-ViTZtwA)6t_&vM1ST(3VQzAxm6 zh2*=O73&IJ+ayAxut8g7mu7syrqMlEgQel=A=(>06w84M#ZP7)FA{;38Z(So)2jX9)fh6O zh#~suiVvy$!&nJ=DXQ4>ISeN=x3J}&LZ?{r12wS;PglAWr$#FHfNTsTS*8*tZbyee z=Vr-Y$;o)16{#PfUS99lCsH}Y9@%_~sf%Ytb=+|#w;{J?mK(nj63NkEO@7$=nEF$p zJSizzT3I~dNB6AG(f7pLX8pDSjnepwTM3nRW)HD+cG*P6u-~&c!y}#3(UHcml?LGS zpBwvvPQr;c)uhTvNXmKowO2y}62O`9bm(u(T`2E${&DoGaM;!TyzUpI%W)rp-QX3q zMIgF9hrS2Fb~yZmbGTeVNRdSn=BKkRf?SalxoPS@1u_uwBoRJ?SyiJ7=L% zjbT|*)F*?l1Z#u{tuYvmu@W3pW*?&Dzvc|@rTRvOUKeOWY{4l9|r7)O?u~04iz2l5^-Jn+Q@A2A*I8OZfH-Bz;J9ja(G6d z%wL;1$!-#p!JXQj>_itjjs}Sj=2kT>-8DhKKQyCdOU15<8c`{>dw2IbI)XSArugNC zzwk7b24x&BU3Ww_g*3-vEWk^Ls&r!&L$n_dE`?I8i@|x*^E96(<0Nv#B!iRCZS$xk zfl7g`#ZLJmSj;!})c5tRFMK=crn^M@oey@XT!0mg2z-D!j*>S5NKw+5RWX_tXO5Tg1k#6>Lb zv36YHC#Hp8=$0(lu)r_F7%kDio9wcTqTL_9U^D5&%WZ_$`Y+oC>9Z;$ZgzNHyP`Zn zEoR!>TpQh(1jkpws%xOXU>5!uStj9@*^8vO`9mi9+|*4=}5snRoB}~N4XcbMQO>hs1!}nhmOw8m&&Mh z_YDryurs~g``g*rE|R|FeXeuuaL=o!Z#T^eFEnr;mDWAZ0K{5tZHjswecpl`9#^&7 zzVA-gdkW6EXv7?Yi<6Usk}M1a%ooLQT!{A|<7jIdQ*0NUZ!>cneqerTU+QS)K^=Qj zG)9A1hG>f9D7`SFRhhH(u4qQ$F8(O3a2lz0dSCFA^QL>yAA9!RHjP`GD~NKOaUP?) zzh|_{Ucc2j76uT&)wNJgXO51oawwuTSF|tQy0!Qsn}9JjXOIl$t8qDARMDAL5(`GH zp|DWbu#CC9HzqzAe(C+_JA;{8$4 z4o}f~X!!yxo221zWZ&~nGA(OGfxVnw1)z#K|^|dHdBJ6BDX~f7c03lTxt;Q)z zSfzx_Cf$Z6oGuuCIyO6@^xEJCew+_A7^h;AQ=~&Q^wXOT5^RCwRct$N-g$EB5b9g5 zM-+7mon9p+!!84}a+@3LLelzHJS5xAEgwQtp?s)zZ44N!)7zd0Nq4LM^q7QVq*O!Y z;Ki5$L&P%&0<_dh{+2!RcyMGH`mOT%7rcQn0AfLe#hFQssMlGnqN*&njrHsMOvf)l zEJ8(V?G-u(K<5|wd=!Z`6nRaPNptTdr;Dv762V^xS}%=*lRZ6>mS-EE@Ut?G7-lL# zuoC>Fq>&nx=h(0?02cV=p6IxqHjyGq^Pki&_~3jj8y4AQG!d=7U^Fp)zvYOs;MlPp zX$64d_piyN{@fXv08Sq^o(ObsgW|7diym?hl!SH51u~9LNaMYhge+BC&W47 z>yMcWaFWch0ApmbcEViQ%FHK$Tu`V z#V4B^62$mStI*O9l85m>&|OF!m|B#W%P~O7-9Pax7eg{E839zxsma(!$h}`m1R0KC zw5m?DK8)=Z^kHg!Ix-)5UcOEp>iv71t=!O$-~~kykrycD@>#ZWh&qQOCPyw2qd-Sz zpLhQNyeFHF@{OYi#euu0iG(y(yO%$CCKs*moX*>Zd)3s0MF zlZ?cvUK@sIx_M2XeQ%?fnuOeTOKphlR4~Sh?Awj*Wo~N@5!sMVK47=-vrqR-^;SRg z%hkv~M3wgb#HUhlIhr4tjBWYx?CR6kh)io!M1V|NqdXeyj^{fj!zu!ijTu>6XCyU2 zB>QwAkCoNFT|Ifcl*w@!Ig@8JCp!IDu=e~9W0Qt>)6L#GP!CMFg0?E;y6cH|arqYH2c{=^4G&^7V!Y>n(Ia~-BWu%7#n_!>hu1f3vj8t>itEF zMWV=~99P>tZy3o^9xWWywRsl0$i|D=9Vymy>zN8`N<#(%KBzgnHZcu{^)w zws<(G-;nU-MW#A-*Mn<#3Gmppd=#(TB}mIEF14x9>GWu28FSwpB`DGUpY8oalQlWs zE*&bRU&;q&F!y>A1lTUal?F=XD`Mr!{|`j1LIXk}hpmVZ;fIFG4UwCE7Sd}F(mKEv zVAUa?2QY@z%~h(4uXIqo!cpoeWO0i;Fw?zlUk9xW18mayLOFJ)69xwiL127<%-}kR zT|yc9H$HU$;%wZD!|XEclQ^VoUO)iEY|+ti^2`((NJ^ywLe#Oq!ObzdNhO`M^LhWP zs3cGp4zqi^duY(m2|)7vE*~4n_VJ`$eF25JZ3FaeR^>NyO_QDfIUgZ@Xge$_3;LZ@ zWEUopMST5bK2j{2`F%M^XxReW9^X+lq~OcHLlPrcD%E}HRR7sIO;$#1dFnyO#d=fO ze`pikzOPYK+=k|OGFGNVd#ItoHY};kN(jcgDG;z{*oh6TlhJoNtm!Yj?n>o+-6Smi zQZPyCZS`8sWu$~wRr_G6X_amlkJ*=shJUs18WqO@$^A$FU{kIF+ihc zctaco#NDsNCkrY2brG|wJ*J7B&!DedN;LqN04qu-2Me6jEp~%lc5Df!CE$ODwmuMA zyMQ$pBlLbq^<6gf_)q`$qsGZ7!BnMFzq1orrBJ+P_&DQ*%8r)WJQP_f^lH@^sSX4Z z3;>4!`~485P*+YlAk}_o(Cjh47XV18J$Kw*Q##o;PPH%=Xz*X6kH|O+AgPAgi`+Ik zIz$X(+a$+d$)oT$g8*1_O*7y=+hw!N=6fgTV`7?FZP9?nBcr24f-D>!Lv%tWD~=>* zD5XUHS;gG_$0(tg^)pLu1S2J#88aO!qF6MsN-P4YCG|c9&8M6OtDrs*q^mB$8(j%PT;|vIiUteFM72`!i|&pEsc5r*93@u_>h^+-KGrz?6BGD_m3Br zAq5GKfridWGGpvK;NX)M2)JS@yf>@H#m4=G8uofU*jbpsX%Ja9R8A6=NyzP{`cMUN z)8zD0B|}fp@>hNJ`Fk|i+sIuk$Ze;)o|U0fiUrf)Q|GkqAP8*faC@tPJ+AyDCbncB zC&JVu1xR0ia8h)rBB3mZp;#eZPqn0~mW!U&O~xnz@7R}L6uIuExVAuM z33!)H%pKAklk%WASeoG3Fa*q^^Zx4=uhU7rni_M1rFXi?r!zuA3Wjs z4KQI>M%*aNHB;s*#n>>F81I2f)SALv%y^;}JoK{1M_=I>#QuE%Kr|AFuCHAS287_3 zMhxD@Cv)nh)2|)-8u=Ahzsx*b!@I=ql1AxhEjB8IeRmsGa^Lq*R)2Y~1$z91w|4V3 zdN-lG(?MUeT&3GAF~)pu^v7RhB#wt}(GM~mEDT>vSA48W1eA-}+3Be4$IriLq%h5H zq=XCPH5sS*d}q>FC@M!NtAd}NMINr~&Cy5PR47YAO-)9V`>-dFf(L8CHLSe z8uY18Tq{641Wi)bnlURSP3i?HHbSy9#doql6e6DinIGrzd?k2|QJx6BR+b>%F0(qe zhHkLoDF_1h{bD2NYlS=fiaikP$XyJ0v?6KkTys$MlF2R7MFL&Z=Vl_69xPjgoyW}$(&X=^$trw;iE^c>jHfxJ!j?Q^Mz8c`X zhJ-!ONlZ*!G{#zN{bH{4SE>MKWBHZ&d4w2jgJJ8>IYs4E#(el0U$=b2g2&&VO?jfG z-E~pV)O&akl;`{X&#{HFaSE~1muQdlaW=foRECZi@pp|Hj|>Lm&#tN0$lpXeAAqR5 zB`f$E@S7Y%^r}lsB1ed71{CoGFMfw8`&vsnVHjctp&)ff?iKPE4@$!+Ju0j93-V>U z2QHqZ=o8+%`?*H@?FfLV2??+!!zR21$~lRfE#Na4_Z1`!PPUSUlR_4Cv~nInrdn*W z5ds`H;zE@sn;Jwa3LV<0xmz!mCp!c<<1dk;tkP+bcyGyvZaZ|yI8K9`e(U{dw#0Dz z!xOB7%wH@}qM+|Us?Uc1dwai2AH<;Vud76Sx0m{GARK$Ntz znK0~y6oO^E3b3K*5f!RXN@X-x!k9w_j+u(K4E-g)ee@4M8<l=^%domPk2Az5#7z{)iR{K+#1Q-}s zdn%&?6um2-rc!F$+&oA-P_E}-n|}|tTFz57kouJ&zMhokD)x=tLz*B(oP+yCPOaON zr^rFlyY<^UjLp?+E28O}9!k8+_Dj@~>7m?*t5Qj>FPWwd36Z>|IYRz5d$S0nWHHEU zQ^VwlMtraJUDWAj@J2Pw7OzTb*S80<^d?oTrsGl#AK$1(Hl4F<8iuIc)fQfNE=px22F!{5<~b?4C@DmU{K-$LS*UbobSQ zbR6lwJb9u{AG7CM-GTze4!r&I^T9$~qUx9?*uz(|;z}mn_B@}YEu(T-3^W=x?|4Ev zNMmvr7!RnBF;hCfFZmP zas+TM41m|$0#AWBI0OCVClRg3%Y!kat7>l^ZHGc1u`05`GrG3dgB}&0WJ_*09fv97 zBbMgXvyKs_3c~YMGvh#5qY9U^1o){rmtYb856!F&G1j=~Qa#Y@D5{OJUC|!Giy9C{ zcYmtbV!}*e$wxc}nBS!vi}fyVuFrzv4USozZ-hk`Y*RIr01S9RJxo17Z6g6VsC8+qK* zx?Y7GyK_-h+I9%GJXGtGL4PW%2E3mJTGT9yGIhvx#rnf_=vFPGt1RJ`>Pe`l5ECX= z(;ZIf*}<{5-5Rb(vQWm@Ui(tDO6S4=Y&E->oC*0qKH3^`4T%g1t$XSk)BZFNyds}C zaprn40*RL;zM|zi#UsdVEWhrljBL>7`?nJcoYUi3d*F+v*M>a6c&Wz4DrynDM7qqh3j9ni|56Rb@qnU59#$+`sTu>>Almu@@#u{1 zT8#YNdee#9@Q!FKPo3pR;h2&{2C+EdAK!VwdMXI|n^|4E1iCK2!o=`0_e#e`m+L8!~V_aVzD8z?eGUr=JETfGDym9&Ybzzhz ze(LRSj+FOQM1ytiS6SP7Nf!lL13tM^L`7l2Pdm(LU`&Io7^FA&mDW@N5Hbx+u|D*{ zlta2@7@y;Cen<;drBol=_D6(s z8XC_|z&m(SYe}_o^W|tG10p&GUre=@T4)}8pqlg76wW^q$+Y7ZE+Ad9|RLETD z?yOhnk+VA&ketO4Ra@xa(?l-P@S4)25CJI|QA40oYGGGvmaKMk;qJ@OGD41wOl`bT zCKp5L9IhATM%E%h>|s!p8Z@-}SmIallAjiTxV~Xuqo$8SW_;`Xz2dDf3TM2}_USan zG8k<3yC3vztGkxhI!UWn%Q>pJ*xY`TBdZ71vsZ{|WA-mq+2gA3JEtD2&z;ikC@KDx z!_~aW4jPl|@eYvzMGRJ`dX2qX?-yiO4Ft_dYJv(L@=--!HOpm%mjTC3ha6&lWDo&w zW!LHM#J3(Xf|OiBvIN!Td>~cX7-Sv?A|ixT*ChjAWt8y-WdDYfdKxzE?f1VD zoV{Js^}6PFeDR_+FmyueF(Q_@)eC|sY4ho59MzlJ z9MZrL&v1ks4+>ry&|R_4YqS7hzx7p38WiD{r#1yYjDN56%7`$_&&en+g< zJwy3}c8_A-qf}IVR7=YopIj-HkYl0Idd$S{#}Dz_{TnwIF=@Pv?QMhre*xTsHH*vF z8j~^PsZ8^a)vbDizSF+GLyjUu9 z%@h2rVa-m&vE2*Y-%Q#Eo6)oi)GChZZs>@#z2S4oW|onfnMgQUKMA>sA0tIh{9k=b zTSE{{86)VnCX<_x^9d4__uU(golOnoGt>?p#kZ)reS9QkH5pxNv7bT#IUh}btG?3 z47+(MjE#y?e{@A;_J$bFyrJN;x-yWum73Us1fXI$;EpYbV$0Ggig zR^2nbWtNuRflsniv5Ls?g;Kq+(SuOor*_%{wA?;4-es|)AlJ&u$wmi&i8K5!b+W+_ z`%*YX#9@`JHq6RwkPX0mAimqPby+uJ(`nE|kdSIv`X>*auT26HEAh5rE!4TG82;_m zi%0)vtRD+Us`q<}2I{-^wb?$n2i&p6-<9Sw^S+Rzi9<~IV({Vd+U=fJ#_7dhsh4kw zDF%c>+2TJYn~pFbfk*oTL?>qgmH4Qhdmm6BWtSg=8J90-Z642nnGp^P5^v&D$Ib3g zw7&m8jxdAWWBgysbk`&YM&O)q`-*aJsHL03l2KNi#Ld# z(cE!`-S8<3Em}=M6br+EIkZd>684r^FPul^wLi4(x85H{UP3!q?1|*S$m8jDS0x|$ znwO!@uGtfb&I#&Yw8r9tY#z*fLPSXo{%=ZcbMuBZwPuVuWj;`F$~#{@^7Vu;BX#9& zQ=w83b=*h=eInB5*F6IUaQ9DK962R($#!Y1D*igokJkFI;@CuX$>1u6=9*f=*Es#1 zAx&FgdC5E&@_%bktX+BVd@D*9F(HzbFgJRMr%-=!XIMqD=G}i%$%v`ZYO#x52&XD# zC(?_Re0{iR7zDw=F_;K5U#X~uh2FRw+WI>qqp3iq8im8c90|CHYtp)YJZH|S{J9Mr zyE-c_wX;5h=l47#zm0sG<@!U~VAJ@1Rr&Tv%YXQXPfJr?M9W_3J(SwN=ZM|Wv(@J= zwNyV30SqdIo+zX@{^n-H{%s=6SGm=}a8MMWo+8uh0js1aIiyh{>#Nzn}`g2?{Oz20w^J{KMQ`m zv2`HZ*E@ZU*71Ek?f%rON#r`<9OGLwmB|(N1QS^TIsG|r-jswmboyt^w&DQK;Lt{; z2_t;20ng=}?S&`!tBUbK4sO;iHf|yWD?BxyyM0THgYnat2=TYOyBQ1G8*beaBB|#T(YaWrzju^b9$ad1T%hTG!Cky5G(H z782R~2~avCA5)CvLSuKEz})7z7q$X{e5BHy%SSsM_#%;P1#nTDMTv2S#b>_Eu{nEK)ANG-M^S1@wuP&>8M$ z(cdFX5a0Ze>c#tlX4YC}P+dYj7T^C3i_>G8Sx%8`+RwxFNznoW=)N+^)pR!VQ3i9r z6Wo3c*`CFF);ONviZQnRBx~y?rA2H72NV=%T8uMH?b%wZyWh8}CXq9M>rJ{Nb%l**=GiU}E zp4$rv=^bazj-)Vs#E=>41fwKnY)zqajdORRS$834!I``a`Z5&ctr-dXvN(GRfP+dfY-Yw8Ds>2S2q8 zD?_pqnKV~2yVIIw#2$R&78bYNRN%?LI{Z97#}|()V3QtfuXn(o6+o2GkvPBi4ehrBqcx6T$^_E)M4z$B_*%Cj}(PT5#KB zW3AV}dHw`OM?k+;mwuC$lWo5~)Y0sclC0UJe%Fq0lB7;fbcB9N{&DOEmTVDi@4sdG zTsj69q@O22M#3Xf8zc_NHKm@-vd2mBH8zMRK?M58KlL=y^-j-*RYV?;)Y}OQtG%01 z0dbp$@fL3ztF44NYjoFI{`J!=3Z;(I^r6j9nTdZypQ%6Y_n9E?D`COiH#I?w;|CsR6y&} zP|kNpg78YwF}KR<=Hv(|_|oTov1&@v8?@SJNpbr{R40G4a|5{7fwE8;AzTv!xp7-t zM-rkt0d3g>d+g_}Pfc$qo)9?&bqHHK0OZcjouUBmP&#vJ&aybyDJfXY$Q4Yv5 z+oj2j-a_;{?9rfORCas=%jF`^(-?`dQFFNpj?+H%CMz|+P(E7dkAk|IKTlY*U)qfn z7^O~eGwTNiU2q@&*&X?WKG)Hk4$I_3Dp{fFeh_2Ic^z7fB_Oe3>HaU|u>U(lTpiH4 z+&Q^eC)4=lY=s@KO)Mbvbr`r$Gf}|+{99_3IWxME{A3iOL|@}m7iaB6205Kgv5Q`i+>M93eOrVDJgy;j3@x9K@C`hg&cbmJIP$p^J^Adf1{(?c+`;ph z&0w2?iMmCtPik7+3Wk;2iLmTchz2w#1qrTr&(=Rt0ScCiO&cdRLo7uU+SWl^(G`F0Ri+{F|GI5NA z%%jsC%g1A0Ah0eKjG#nOvqX#PqQ)EJDWD>(VUmKZ0lPeU82ACm?F~75gDzrgYiq}U zjgCq{gLRC|D@G3rPCQz%I$n;x3#i}5@fj>({Ba9lb*1^dHdRom^Rq^Izy+~JkTWxEX$|`e6gGa<uA zifUWQ)?@Ldq+k#!pSzt_9t2P6_Ie^0B`{v+(&99J3|#|Rke&c4`Ga&K0r+otK3J8F zCP^`$)L=M2`IV9}nrmyPiS=6N`3MVFcX}Gi>oIZ@@W>mvSzQE#wg$mXgt=j2I=RMz zXvY5C|Iv^2UFho-M*g9C9Qkm1bfjWkS=nBz(+^69H85^VbTKEfaa7J*)0 z10-H@ax!HGeE7cZT#P(iPemUUi8OmLGIT8ye912|y6LQj!w~&CNFBGa6)psFjCYW- z5BC_8_utctKbh~1XC1=h5>0+jy0XZOTqsnIosYJ zBn|G}4apYx%-3N5C;dCV)A%~rD{4RaQVh_8I3c;tQJSIFjFtT?vX9gJLO z<}Nq(j_Srkj9^Uoi~Zi$W(pUBSYI}Qp8Jj8r$+aM#I&_?UW}@lb?>-eqG1_3B6i_c zl}U#{zUyDZ39uXPI@`UMhxz01_ zEA|tm=n^SiqzGzp4p+UdbKFf-&;XT)b22NS3D9hNEAdO1d9YE#umMAE7*k#(h~W@R zN^6h&&>mgrTSwC?3+5^oyS89$5~X}$l5gL*XZ@8uROGk3SM`XEiZ!f$Vd!95Z zAIvlIg?HY9@hc2KFH!ng>-_uut8Q<2Wx{htdkcU6s2r!zZ}_6{vIBLFxF65_-T(3c z7oJfryN*lVv;D`uOK%0UN2)~xrPdt-H4%*#nNSGP%05}`ET;Jz@Tw`~_qHr^jMQW4 z%vY$SPk=WL{O%l1judZ6IcO9Z_dL3B}*(ZtTmroNcot+P!#V5gp8*Z0q)$HAi+1 z0L#Cs0SpXG*<4oC?}P>gGH`FeUDzx$O+|<3Bt@qLHU{oTda-xR-V2gaw~FI2x&cE% z3t#z_KZgZZ|Z#V18v=7j+ zqpu+P9)PO0Hn&AsUUzCd4-|=GCwTnulRfBD8SPhg97E2|fl)I$48Av|IdoLYgg(os zfM}W4ib8yHZj)yiyoB|zkCCAtjt+N?lk(z;8DBlxvfQ0apf}1cbmN$VT@je{rRK}- zaSou7qRPvgvsM+5~+2U&MuAJ53{LMW>22l#tAoXmxiCEdJDF*HzX=Fv}6bi5K)| zK=lP#KaUKY8+=k_RiiIP(LrJT@QI_e^YXJgvn_eKCz} zgth<5W)jN5K}3!ZlR>XIcU03!shOFBs^fC(ZdCYD;rwr*W|Tj{!w%Iyi*$N7_9n#_ z+lZi@R~a@K8NC&x*YcZxBE1|ueFc6;dN9qk*R`k`cfI4?RgIpYQ@4VD7>9M=>XZ@} zRdHqfAZ22>^0T6aUWFasl31Ek38Xi8+DcrS$H;fG2B+xUdML zH+>9!?=T51GF=X-S5gdhW&#Uv%`yLn9dmxZ7@8NOi+ezkdhB zo@vEpZsElC>&x{Jve3GHzw%`i<9i`ee_;pcqe~>D9U|xem8)H(g219DtfrmZudMRc z%+d$xX%22oHrJCBObDXYhDhEKAfOp&g;Ej*VNR286y%O z=m*Z8o1Lb42@5Uh72sHlHvWd!sc3w)`%_Q$sdT`z^5OAp@*w1gB35i}L7Corlq+Lw z4f8QZXH6CEUN(gTHe4kxc5)6VNWDe}F=NsMiAW}UIS|RDq8gQXXl)kr9%OC3h_#}a zAAGe{A`kFsp>1uB4G3c(%GMq1*L2+@dqepRU$3XbLMx5cd}ojTgYcP#myT_=DF`6#a0yHgA?JMb1G`V+2Q6h1(!{Y%ruu`9DF z1P72r?(a`?M3C!7*yQO@{eZgj{j`h|7Ob*4EFiDrg{xRu9drK`FIg`T$~wjLLcy8K zAp1GxKuQUjd~UpbreI8!h|7-hYkt8p?&;F2>P$$@^iQK(ZsdNAWqz<0z-GF>ox~`i zdx2)}yb-0#y_>F5&F(7j*6Lg4tRnC`L}3$Ce+AU_SFqc3{+-F&O&JWVqDISc=hyd6%39;DkBx8jo!M({#37Nve-q3inkB^Cf=@F_Ku&tD3KjvgoylL^99USDK5GA#n; zDfHONFag}s1%Jx=>|W~ETS3PtW-&VZrfw;0kB%niqeU9qL9VRyf*t){*Jf?~#NI!6 zO)~8I0nd3@2Wx_s^avaak;k(LqnqnJIcH;fO6LZm3fBx)72s`vr>lZz9={w{t6m$& z4}}yy+o{jcRVB2lsQl40CY962mRB+qdW{h|!M_#!U9sh-{OgdU}> zjqV$))R#f^eOB|E56yh1F+cOp67|kW0BP6XA@r@c2WkoAVs!4mC#9A=t_hrsQv)o2 zYUH}HD%xTNmb%f}DfZMn_)VnAA{@$v4-f&u7rRU7x4cr?5K&>jQ+%Lw7XLq`H(Bf1 z;(rD5dTf#w><^sj?P&h0I~g0@12tZ@9z>xMV0z1++(II~>hh&9^_|9jL9hhRbt#AW4lKB+$pVl1Zrk_>2h%+7Z|TmWN6%3Mw^IlAbR!T+rjPyd(D zHD@2;vbgxpW|Oss`vp4Cj6JAOq#c1Wmx(hjy=qeFe)-FZ_lcp>9jVlP^5%G}ML-t( zBUdoCzIqY^8J04hQsed{ge12Np8Z8_%)TZ`H}W&`BEu{RF}v*QE=#7&6a3&Xbt5tR zL*d@mziI-ax4m7{L9{Of@TS$+Kmz`J%5fuErrL)|vNAIskX`Hd)Ml~}5|PF&;!;eb z7CaIl+LZYbaSD8SjklwlhJdRk>WRle1U5*2tG6R&ADZuv(?yqaX1m>;1~}8IU=V|g zVVirTiS=cATr_&F;qrn`Tc4!A{l@P!Oou?e>a<~VD5|{cT2r)O*P;%+89-kdo=9b^ zL^-#5e|zpft{jGCUbpOsYIgraDrM@24B%6E7)ui*p2~QEx#d@+&=C zkXgLP_q=cmi(`6&)`q{UmD9AAn=mYXLr)lnkB-)*1c5o#HvGI?FTEc;qI56TX~k}q z%{1Ow+miN43W2RCo8}syw|ws8wX`y*MiO)8VHCtZz-4sVa05acuL;~7rB$LUlSaep zbX{741F~;sYs&eUEA4^c_|_N*OM9oPO47QlQ@qd)nwnnQOzj642Xsqw#kb|c?`~&ep*;k2PczWTl>f8FW(XQ$RBdIM?V;q5rr+c z$s`z*zSQ4S8UCVMjLMfgaA842K^cDBmPQ?!3{EBq!A%My;K8w|%xzmTrH54XDDBH< z{`FY)nFJdJ%+ipID_@H|et^7yl-czj!PCE%gtshnq1{_^IGL{UX?YPi&^ImPa{h>Y zF`!fy4K@_0vkMtiJ_bccM>|GGI;%$@(wrgr8oKN%K2{|5X+2_BRqzW}n`EJ9FkS@V z@rE5LFD<{qO!2X4tkxG6>Y^-*{9@K3A0W(^3>d<1JjyZ9h@V;eL7!n_q)}lU3?Zl( z6aQ-`#}jy23krf-v$YOXMVt^~CgWx4c6Hp$p7GArLToNT_a)Hn$v$9LUi~}>kPVcb zc}%%nG7ig7xxop%$%ko&&?7JRu2+~D10U_{&mBwx?bI3&; zO2a@6m=nb~@cs6XEa$h<2SOZnRiR{D0iu;_i!pQF!M+P7a>j01W5zb`bL+^Yu8@>!RI&8&d+M zp5Svry@OiE1F15zUtqF9V7zPV9pd9Hoa(LCv|cE!>_U5Q%OuWH9!6+}jOMZtA&D*% z6M-~{L1M~WT!&{Vtx23}vb$4$jmSE@0NRVolJzsqF8WD%n_8;Nn1}xdb2~ z1C{C=InKE3xGc`AIO2p_KIRKcXR==Qpu9qbvi>2T4VG^`__#bhxW?iCOp6HL>3hPp zy#FB*`R^@Q6ijP?TJaBUhn7wyC$Pw^b9$@sPjhvV!6OMNE<`t#c0B%1U2h!|H}3mhSm*-bqZiAv1+o$O zHi8O5vx~;t?HynoeHqoG!|jZ=XCb4iJKQ&Yemtl9uJ^U(ui>41dN7=2*4>j)+Vvuyl@(teIUd|LiNYNd_V)g(^&@trNy)=QVQU!PCEN_vuI1J;k!bRiUJ}_%x|R zyu5yF5fTz6vE7M9gdd4ZjEzMYW^eS3g>Wj=0@v6gQjGYADzjK`NFLLTW*44%<3Q2t z^r;|@pd85op6)LJ{c2M#e{yo!_7TL?YJ_mdo}0eIxTzJ%r8UyEikrbuQ?h|o&w}GV zfs^VEWOb`0TM?y{$c>J~9t_vlznMw_9U%P#4UhIT{Syga z;!|HxDu4YCWc@sKpP{B>T0OF-Pq1IVN=*xBwFcSJ(y6`s-5R?5088AP96fkN>i+u& z6bP*w@eD+MA)1yt=W-Ly|9gGJ-%B*9(V$rXcn@<8|5_tktMu5~q7&xUJPKtz%b{*5 zu!Htii@iQezZQeh*F%mQMa03#ENprW#+|{FQuoy#6>}UFu5 zxTLvavI}&s30tY5;sIn{eO%<^Ey5YP!R|rnk}X_FnKP{l$3MmqQp;r{V&T>hVy--A z4y`8o))Nt#r&^Zdq$g`ysgc5>TI@EoJ}u+^Fnlt$b%WbEP~rbRu8PrUb5?GUL8hSp zPzTG!pdHG!EKs!dz+IVR->t&R$gQ<8-*|%SUV7~DJ*>$#Q(_0{OiEgsj-THaO#c~S zd);7Du&EZ<6r>{9dwE2v;*foXQ3am#@$13}=iLrI+RO0mN>wFN-Y+>*_hs z_LDrO1b5Sy-TohblQk1jpx^cE>7C2?2zX|fMR+Q$y#u?SIf&YJ*Ia+mswiL#Z&`Sp zwA_eQp-v94@;!)XD>ivR?1sLPD%gKTSW_Wv`DHazH=D7(eW<`(_rn-B(wFvPh~DT6 zq!$A_i@*ihs>5XUs1cC&$t>f34p;j9emn6Ec$|YkNd8r^I}9r3;C(7ukvcUPDC-1X z&zIXd8q@q(&{dAD5pi_xf>P^rbgV0x+;2wY6zVwK8t^vEgfpCN9XZ+mB+#Er zG84*tQ3$M)?|4S*L;5kj-*U5C4ol3dpqTzWQ&Y)WWbD#hzIyVf3tYbLa(94l%X}pq zsbFmQPW>;Wd#u2I0~koG@9mU06O%Ot=B`6}7f3mvLMVrhv?EMRW!p@;Wtg$4OBb|o9FHR-O-E&mK%rngAI{!FcrPh*>oPG9#nZp z9DYqQvhEKxwbXQDkvO$e#Tg)DmDykx^izw*)Bk(n?fBOs4x0fdmtUndsQBF$l_+cn zZeX~VOo6GNAPN1l?qaP)1EVV7Y3a`^a1E*} z)+Kc_IS+IlL7zfcgD~bY0-@n~|I!XfHUc4kLBBQ!%F$uX!^&b)lZ_a%NYU3yUB?L> z6glpZnob#Tp1+uX->#xj39E>r@+(;%)-x)ORGaUxpdlF0w~Q(R^#b?g!Bi2EvoE)gZ<40jdSN z1+pa}bTDM>R1^L1zDg`G!gevONbqzn4fjJOQZhS7ySw=zn?t7^wD>PjqX-5$S?a_H zqS(1FWUaF4lthyQyNRYvyPZc;GeUVd&LLrVP}8d6?Du5=p+PL#9fcN(tC}cYrtEOH-yY;1~r&oNx>bK;rZ6X0q7H15( z$e~<|MZ|0)gk7o@_%HBM<6i1i_xbPd5zx0dBTl1LkR%!zq4ZVu@MvO~KN=T+4YQh> znt~HG+IfnLA$p`3Qv>-r!a;tj48MEXd( zv^6ycNS48S^sQ61AlEaCly|Z$VAasQh5+d$u<~nA(PgAN_iEA?F3Sf~$-NcpB49}ZSi#c0r zpwB9}TqHI`=C_3+mjz)qdKt%tq|ytTYD0&qX+s~f6au>P3*ch;PX$mVXNH)~NWYoE z?xJ%=ozNs&<(>_AA!sL0J2{C$$Dyam=989ILDOe~J=l&7L}PMS%3+uuvM)D-W}r-^ z-rs)5yZSpQRPt0B9-#BlC*uaUc2%GjXPdY{>PidAeH485J^r2lLH9|q1^*uPHpz97 zp*)kO=!}zA%CkfrEG2F;y_4(LQapn7k~2?Y=6eKgw0U-ru-sx6;P+|cn{!>jkNI<- z)-bTtx2Ynq)#eOkXK90uVq`8H&(m4r<5{XUZvgw03`g(YHxD_BsGQwlxrXFg6{M37 z6Do=`uCyu#TVyrjYcp(+-xZO8aik_8UDD*5(KOb%DMUuoZ8d!TYPS81{#Oxq-C^PHq0_^f{bZHKq0Q!7`Dy1y)y=%7mcX`G`2$~NdGC8s)MH&s(R zY+-1cB7Lxlpi6W)yg-Ay$8bP4C&?tArWi9bI44hlg-<^k38@#>7PqFA()8(iN25mP z=H?$BIpjEP|1lh~Pq;zfm_WChy$a@p1*15|D0~)I*Yna)$v19i#f#(I3>MHsMi==m=>G6&?36rlj$1UTTm>zJPV7Bv{W^*kg@V zQYvfBv7+wYvOi)QSOW|Py+@*PYbS9+8r5u|iqKIz_#=u zu^o)AvxVLz5B|-|NJp2b&6!rjA5W8lYbhKpFJqx7K=&PP-sCpBY;bh0YDWzA#x*^9 z@pr&?wjZY-h}6oDJ}|z+n(d9n|E>U7A}Zf34NntTz6I<|FDCxZGhd%_bc*lKZ!Ib($ zd+4=LtYHz3E1#S}sLJnVT4`b`+cV?O;&514)#qwf6Q@eA!oZ$k_p6i4L-JL@EE;wx z6t3XsmH>~3!)r25Y%>`|MVHgTxKrInG@F{T#?iGFsxR=xve;#9t|(d|62ZjVn-MuA-9pr#8ZsuBT;~bD z(axST|JyNYn(ncMOVL8GdiR;K>5;ltbd3=Uv_4sD35qnz;cZnF1{9RQ&e6%bXh7pv z=hepQc(db|`7a(sdMb0bxN(a>cc;bXC~$FYu2}Z&?#`1#cDT`In&fm(ZTAA%4#ELG zcqaj0&qL%M{OB0KpC1X`Mo<&sLm!!pdHoF*CV@L8Z@=5^Ld${n;BMV%f{`vMSjQ{$ zga;8{X?jJC&TS|VO#FV<*T7l7jH9k4A3FLE{m-t;=Vo_F9i~))>XcSD*E1?!-4!g| z9i$`0N!t~p%}&o&?1pwYWB#uk6Qu}v>ec0y7?Bn`Amx;%`FJtSy>w{fB&@Z^BypxC z{paQ$T0*f=lQ=9Jp{{|NAD2cqv$wan)8cGqlkvVmz!vtwXHqTR^@G&{b)y|Rs^qDQ z;puAdOpTy^@2NWOa+=%}y>b_@0|-CD@RwEl6+`>Lx|Sc}!9wZYr~LzUaKzs{)Q z2!xP2Tg+hf=U1}TcF!W8&K1Qu5?Zcdq+0P6>O4gDmFsscrP#9<+6j$3gysiQZau-f zNw#c0_pmm?IIJV)GLZQSnI4j|DGq;gNaJCNe5T-aFZ7o0qb`r_sqf!eNp49H)>5_o zy@@}!P)FdzQmy{S5War0Ao}oCou^txut)QgDyL3UZ3g(FJG_>i2ESz6(o$& zLLMr#1Qm`2*VS=pv(8Pxu-<%(#3v1)@ZB$`l};`=HY@c*R(a!MV8sT@#)klOr>gh` zEye6#FRDb@`=Gf*T)Ps{{sGoAbt3*>Trj}e_{}80KEo`7KBW!ogUYoL&6HX(dX9+7 z!5Or#4;`27^jusTD^-f`)e$C_X;XsQ2Dw_<`ctWo*kx%-#cPJsNw&Z90K<0*xXMz|T3TyyvsR5T)M+FjsJq8^t1(KEH~fT^@ae2uh~kmbH4PRg@s zhO`uh=vUM`82>nfLYHMOrcpH@X(RjHeq24krt%u%la_ba|v+s;d2#V+q%=ucTQ1`!G{ zqbr^w2goGJVi3zSWoQ*3y`$ekX`E0Of`gMBr@*TRYy-@Xp!dxwD53x_=whzRQW61j zzw3i{>o9r9iwrlteJd)VQEi$bjJvB}w4~cSEunQXX2 z)Zc};+t)m0@#3(p@XF}5Z1`5rvBy{;lFo=grR%5Gg5CDSwnJdYSw{`(QQ%51vTmqk z`8nBoH0$Zu70#zRp9_{RP~yJ4_cvvN1zl;|aYk(f*LpEvo?YT{dU23q1Cr*__iKlOwS2?>3*5OCx5nrCc)D{vln1V)? z&L2F_XY^$UxK?gM4Nz>pcn=Wn!f-kWznQhTu@b8FV)yUlQ7$X0l(M_z8uJqRG=#0E zZA|x)ue8Z96FHlG5qQzVaYixW1f>kIb+j9%hHOdSw`OX+|48-IXNUP~3}aQ{4{X&3 zpc**!XyNLKbcjm!RM)zDF?4+~jX%W=OA z3G_((m2M}qk7|~Vt&h3eO$;}_%BcRFpxQ9i>*?y_($o(55PI~ralb&as&-s10y&fK ztz%WJ2~2AzE1pJbm5N3C*LL{WTzs?Dr6|I)zn&IE_>q~F^-tzL7pHDjf1k;3kp6na zl{#*B;#bYRNr6iC!g=lF4vY*`#MY`#T6_*D(#ip{gtlGLYtWMr>8$kc5U~m0z_B`5l-&hOpx|nny=B5T|C0YVh%Ohb7XwnkkJmI4ljSF_7K)T)4i%4LxaZ zxDl}@@}13K5>I%t|4nKu%hymstQ@QUjwU%$3eWe8t_8Yjg$KM#UwH>xe5Dnu7X*;F z@>Y@bm&sugv1vR){XQt3uFoWbol3nBRdNH9O|ko`lC~0{`aCjG^0wwFY5y|D$~D2e zxx|o?og?=#2VT*58*NX?>!4bFZj;w$8XX`Rr{Eeu%N=&e9}qV#cTiJMD5t#~b+puT zCe`iwJ3xfXBO)dsfZgOZw-{JlZ>Qm7G5x+UF4lryq>NKAas?xre-^I%>9mG4iCqL9 z6+R~6aJ#2jfT&Y+%J_Nzi96_W*h12e-H-3({jd#=N%dX$qKHcEYw{j+T({nbem;j= z%%C^D@#@Ghg&`L~L2nFVUr#6lxmb6dFN9@+ZhIFUUN*@bt%^cH zofD#PZIw(IKNiyp6fN>+JrkIM!XOf&^G8#u_Q!<37<1tsDu3`Pg?&tvD0pF8fznY1 z!`W|klObCb6QX=aD1kCD|G+jCt#Ov|jf`L=?2I|7@0Hw0#a0TOOU`iTch*+=>`B*| zU@;tj8L8HU`H2eG$xQOyck$A2)J(0Oz@`i5322GM*qYM4T|8P^Sey6+{bXM8UycRM zHXX^6llg&qaiH62d>EU*(0yF19d3pYVl?HU1?Y~`#3W7nlcTtA-*5%8t(mL6JGX!o zm050t9-0SF$P4Dvu`7Xy)+my$!J9rj&Y`@1SuYFn-C#28jn1KQzRr}YPVY}2JV=Et zZLLq($$`|<{82*cNuQ+D0`mM=SsCgFJH0YHsnVytY$snc239|CSO^in^0&pXc>?qj zDC4uuGqQL%epprtGrdoSq4JxPZGosq3Q`*lO>k{VrrYnVj|6Fr5p=-s2uQk~jcnj#6*==YL>sxk~b-P;qR4ppplPhlHyP2T}mHD;p zhOx>*>h8Fc3o;1m(C-d^tJvNI4TQ%{{@hbuDG=O*I$a0unvZ7j=%5Zsp{hhPIBmf3 zG6}#ud>xdbS^MAuUBwd`D$hSQUUeg*U<-N4g`~y^y)i@*1mcqRR>;&Jlhp1rAmK4} z%p<2(5#@pu8+D}Bbvv-}^aumKu_|;djhCW7e2k3)2IlVWYo}QJ0Xr_`RyODP_+Z*k=3K zgotPd?tZv0q@k$j)R{G<#^Aa+`{0CBo2v<~6*cemoa(9D2fd!JKL9NbId(LRl?q){noHV~U#9q@2rAv2rx3g!8VULr=0xqUv zBM}c%2}x02XtEbgx0OlzhS=P?{Na=|=RIn}odP>fkJ4)!+tB~$dn?z-oBZwx6CjQ- zLC00ObroVD)zEgU#$|Ylw_ffIXSWP|EtVr-o!_L$$ASdH|AHJAg7Fno7mG{avmT*| z=ZVCJ6Q6+*=8se?!-$JXhifX1AS@rRld?wG%3t#fo#KeI$+!&OT0SYJ4o1CT=*jf- zSOL!+)#iHfV|}$mg+7fg%3R}gnk7aNk(2=6Y)o^DbiEf}@l`&PGN(dIx?^~Q2}=ms z>(=X+TvBt|^Yh>dFLZcokB0hs*0Z8w=`hAd+66mFQl%3TFqOiCx|Cz^dX!RzPf61O zHYRa3a~<|R4kvl!6=CcN(9Np19G6s+A^LT&MzOpBpBHYZSnCW$={bE$?}SG_SE|<1 zF8SU{&vJNrf0Nx^)F0;f8gUJyc?^7lh=DaVV`eAZ&YHEtZt$PAY(T|$ zMEFkXrw3AMJEukzo|qpFN{nu?0M@&AbH~3tEYi^7@y;D*VJ*<){GwUbroS0$k`EL# z@_6q5JOw0)fbHSDDPjMc4)91QEC!&s)H0J|@0WC*0+GEw zrv9D+_O!B7+oeI7A3mUuL!9&36l`DrpQ4lOy)XS5 zN`y%Y^Fw?O-#-`K-_y|1RX0?&_+6KgkW{YY{0U>Z_dQwfXrU%U&p=#l_h1pC;+P!} zC8?&VFB;&&NJ(Pyme&#UObr;fka_}Fp2eOFNs?RYEsB}5U9nB}9g>mJ=q&z19<1R1 zT$|m2949Lf^UZ{ASEpHIc~E3IHa1o^1|OJZZAZOR*t0`G%4xDNHy0RADmnOKAsHG9 zuSLfIYNNveAlzT56=u8v`LB)3jedy+4pyy{MY{BdLa0i@Y(BQV@fIc-w1`Rfeo?b5 z{%e%Kex&6&lM> z|4P(M&S5j2?jE>P<&bsi{^+k^w6p(&6m;YNsba;I2tO&cFXSPD?s@SVt^}?7WO2&I z_U3OQRRA}4h)Rx>;Z%J80$@m1Fji)IVhaF{ADZUAzH{o;uN(UQ#DdoZK0)0p4s`y^ z2uQ|6uQo(D-Qad)iH+>6nuwa{VgF5ySkm)COs&|S)PLa#)|SLdXp|H$GQxElSBTMK z(XJ|BdVbi?ANOyu6!R`)HR&W2WJt@#h%=gX(mBG`|DPy_c&V%rj9FmHlG97Q^gZ$ zn@^8_zTC~PNX`ilZ+q5Ijjkc{vQ28)w^bz@N*@cwt3V}&2eL|*8rrc$C*v?GY%Il) z0-^*}@HU5YpA%HoUd;5;!2Hc#T1jk|Mjcjx#L=Ink`g~YU2Ml|R{kxLTi5If%n%J> zF=>^u=l;Q%*Zg+Lg*hG5=Xcp`l!gq!2RX)$*lL$A>7=TL#C@Phr(~6h^kF|da5=YBvQI8R6r|$ju zn0(Z@O6n`A*UYQB_`sJ(D!Ih6B)2b%o5Wd`dL@GY}h95FE)Kt+i zG=SgD_q4^jELwUKLS9Aj4k_W*a9}jG+F(1P^*NSYw0&)mZxyb(L_REqx`Ak>;~-1S<}yYYi>u(*SfxL_i0q=_~pk5tcWL?W}BIn)$0R#L47aTp_ zBVhNWqn48{n~%G+AUd@GXg?0C#Q4eX#)DpRTur(jpC{Su&S|t1c7aS;?J7qrGh1`L z1Fhbh=+IMkXlknq?P3)e_7)u}saJmML}^%*}Yj2nSlC4*9?>* zP~y)Am&*^XzPUi#tTdJ{oh53p_L+`a=WXj{8HAVY>)PAuI4zTmt`D2qCNV*9>huNr zd~eD58!FYB5zj7W4gDG)q+ljxn5TafKgV5F=ZpDyRr=x?1Y@rDAvy!Fi}>sPZ@|jN z-}%i_%MV{cn-CqaSTnx%%k zBlxh5%{1r67)ud_Tw143Q#EybAeB7);Uso7LbJ5$6NIVym~L;0<*BN&TPnyA*0}`A zl@22m*UnU`?WXTDLH`yL?aL5Cg32zP(&}M2d%X1*Hf9{YNq;>HKg%kxpdjUt`*0$9(i(X8*OsQ$E{yL`nV& zl}_)=Z|~3ZC(<`bv*f4QzSXlu;}1Tv6Psx)*m~$U7rDB!{+TFS(%08(kg%K17$@N< zUJP#;{}TXkTP|yVXuF*%nvZ=E#t>iy_!0RBUk$(1&I<4%hgrb4lit5Cz$pF$svu@% z#jIb;AXG}{sA;NtEl6S5wsZ1CDn=bDGM0*%KeJ|vzBS(A2l!xZsqh(dWh+e%8pY=b zXwhMF^-&SqT7KnrdL1W6EoK9hX?NU&JVt~7cl94(K<#@D)U0M=udmgBT9f$?#Dh8r&v~(;Lk3@8 zbAjtEGUp=#je21UUCBWPKB9^QNCsdps@tV*OF+5Os(?9yKJk`Q{@L!0Dw6VK8N-Y; zP9|Ya^EHqA`E$>J!g_Wn~wrzH;c+=&)~|u0CcevQ9Vu z@dq|iTH{b!cD5Z4Ugp+AdDn7>UgglZ#sT(~nu?!;^(x=A+(UHCvKfL-otIyu0BfFD zu^v3&8-V~-lw|VsCfd7~(1hBg9}SYTkm~5h3pdzh_ZDh)`D~$%$a3n$Xy>;iRvcZWz68Js_(W+jtz34>IQu`j{;s>P(7|iD6Cvx_3B{!`_kh5aAkE+ z2k626;gZw(O3%mzKj)mP`!}B4Nc9pVxt+HT6{vULK9H-HQe{SHPm@R%wI@VFpq_o>SlE?XHEFf5<3Ul{=EOntnu!scAt-UjJ$ zDyuFQW2u+E$XPUM=1ag^>_HGEZZRPyhL=zH+4SMlunjt%dm;h;jNrL>Ywb0;lY2=)b$Mi#!XkY9#a3Qnq~8l-|lvy`|xWWqF-^mNd+AB&nGPcl|PjXKiXJb?)yJN()FV?y<9A({>T|pZ}GNKe>pJl>D-bI#w zRVrgOmjrbU@~D;ty@=Z4Rv7K6v2%o~fC{f!p?X|gS`+rKeX_1wiCfWzh zLF2q=?6qxASA`T)?{%GBG}oZsNfoUX{tqKHnWPcFJ+1gtAAD4yHDJL?9`x*DE|oWM zfB8FAmeoC1k&BzGNq48gri8^4^O#$SsaKP4oz!79n97HnZ#b2`kbGfr1E*AblRRfb z27FV~HHnTV;gm-pi_BKli{qslBa_S+Y!!98HD*Ojbwi%63fN zgVH^w=!#yz-->y31N}D=xshG@#zVvE@bWe+Lmoe%5SQ~s%`l`U1xBk{QWwfnBg0fR>^&d2Q(HdTdy*z z-2MHt_dN3HE|^e{V5oZpvwV-#F4NuKlN8H05bYv%Hjgubf)`wjEm6%R*U?4`0* zI%ZtyK(zbk)38?Szv@x>;&z&irgxH}XkzlKp6s4TWH+0x#Y)!cV$4Jg`$4S%1iYY+ z7=#5~%UC*=j4vY_jgqy2q#^=}_FD$&HGuL;z~O8$@L`J>skK^*URvBT+4~Y9#a0{s zufgR3C6AQl6+O?BSz5aEjfXHMaH**Z0cP4af{9~QTM3v1gC%Gw$1m%%_(puv)&j(F z%(;>|e&j?-wnr;*{!v5o{&K5MFu?!NAn6^FS6mq-taUi)M_?JHfvVC z7qzi5mTS0qhM5S%+a&<@oAOy+9M;p6ZJAA@3onxE8>#+i)%tVxwXk5FmMYEdv$X$R z_3|{CqAPUTNwR0>Uw$GkB1xj&b<+A7dK9NOBT5#E)%8XBeYPy4Bjk=X(5s;4Y!n70 zwvU7P7mvOnzEn53Qs51O7*VWZjShmpXJJsKjdfV~ojDjDvHDhT1k~{QoA#tx2i*9z zq2vJyO;EDD8MROHKcu2C7TH5)%C;%!(2;i3LX-wa@=gx;%=~A&PLAG8EY=M(i7FPt zTCTf^nLU!gDNbOx=T~8_j&LP;l&XmjoLQKJu?K{IuCWlVrlnY#N6}&ik}F4zRwl^< z0|Q$V4mY}le=NFZ_@D_ijV8He*qj8ZPiCQGK{SdV*ibtKTZ&mfs+I63v0Gv10|_!Z z)3Nahwk_^NN>b3}CBRnuosalai^k!})U3~lhe{v=2hzH=H76axOwmwUizzc%wnJhA zl%o9M!OT3P^=AJEeK=hHK zOru7#o<+3^-qS2!e4sk;&ns%qBDv+^sP0B#y|8WVhSz35`p<#gJX05u%O5z5xG|?v zA=I;kpWXr80F$?+z#Zu`9`mIKkA1%ux&^!7aEQBsx@Eh-rQ}AWpy5)+4CkJT|ILD) zA`w3OX&eqVDK!Yk&23T_B+$0#NbQG*#^U+^KM-YDDrE*FzY{*Txzg>w6Og703%4Dq zy}dbtqv|Zw=3|Is{c{YUPkp`GAui6XWMclnEa(xCxTe_DI&b$B=9^SQaq4R3D2vm& zLZ&C`ygE46?lf-M68aLDDY>c}uV5pjEXpm%I`6$gDX2u#-Z!Kd-V;6z?Nir)UsC+H-rS#R*S&g>Yp(V!|RC5ZFod>Bvz48-H)gYO0+ z|G0Zw-7LE%wtgk)$7~^;XbV(U*M<~3TLs{RG?0VN+dYmWjeRJV_6QBN7TSbmY9ANN z%y8ceGx1v0P=}wDH=lMc)46NwpPK_I@x~BINvUe?jw+hS=Zo%7llBg7p#+x|RAmkk zDY(mOeG|lk!+#&sawMJ}CNsH9>lI8mxLLBPaXlAcJ#bhJZwL{i{*aEF#)DPaGS5gm z6xoSmpi^~rN9AN7b5vZNcq1Lb+l3GfbiaGu+rKR2g}NXo5!!=gD;1rn;BHEr^M%UA zFcg9VRHGRHO9ZUt3?19x%r%WxtO|u@@B2q8GF9j|75Z8Aj0k(RR7CrrDrse+klrUa zi}_wNk{MVn327Xy&A2|UewFMOTd0hIWf7o}7w>ZgQaRuB>B1#aAgWhPA%&N|+}q5R zJY+ulf<^`&e#w2%SYHCMS4&9-y8Irh&qp60)66CP;UuxAg9JC|)OiW7R*^c3p7@0* zgscEP+p)!UBxQ61NMl1t$KDN0Eu72l@kx)4jgE-=kx6Knhb>DmK33A#Uk=)D7Uk{e zfJ#5&nLuZMD1XI%!oxgbHEO*8Zg2Oqstni|7&lu$93Y~?pn9x+wg=(MC*JJt#&fNR zC=NlHs-uJq9E~O+?}}K1sBGdBe7SV3QdL<+elk5P#EBqAk2BAJR7*Q=-Ly7YYaaTR z6J|f8(*lzJ_Os3}B^ZY_sal>2^XGRLs-b*?*6j}iW6{x4u?4dNDf=5+?+B?xR%-IE zOTBn)`p?Ny(@hdlWg2vTnzLmTFXSX2DkpqecCcs!hVfBgTqJ|}44s2rMlnl|8@1%2 z3#y#0N{LcI5a@DnBdHMs?^m>g3C}8Xf{i=MCMl|mOWCykRBcDPyxY1CI4L_jU z*|LMf3IzzbeeHKus2EE!6r`+rPl+ix1Bc^?;6!=#J(t<|`5xgR#0j+~>62^~f30cw*LGU@D9k7d7H{rk(STfilM2P2JS( zec$Y~N7O1H&Vwc;UYTNHB`0@w^h;%JWvkoB$chIG^38Uk`U5Noqs3+*?6hLC53nfK zTQUB}LyR$V+@H6Nu#z&pt5egtf4&6k^CmVth9Up7xy(>+qHTy{^LVv6u?N>;HAD`F zjaFf0k=x+CexDMnRxm60Iaqs8t{%Q=`C78Sqv=V$tsC9pQ*O3?+lEq={@^EBAZr1v z6QxVn#-wV$1iifwlt3+h4C>0Lv`|0xk6D2LaO5@Ujeh5Eq$-mZI=67@MenDOrVI(i zD)m-HMa3+@lsxS258L~L#hQHPz7@wQ8j1Gy;^ItZkTWyt#0l@L26$Kf->Sc&#*N_3 zg{Dt4mjahyh;7hy9B^4nB%oGC%Mc@Xrf)Urv+VKE)I>z*#A)gWXSfHQZ|oohXB2VF zsp-Vk2zj1>GQ-|uM(_YaCm1%&j>T|+>fCW?Y?gNW^)Lx2*u@_|ejd)V@cUJZ#~t>C zz*0(jAN_IX{B!9a*gZhW8Hzr?8BzDK_91a-eD+?ZIdn`56e*E(;i_XE_C7Htb}{S| zDayH)(LDn>l0F_QgsZat77n^xD*g)NeFF=HZ;sw&-d0=)M5H=}6D)8lod`4MWQ(FJ z1g1-?=P(7St5f<~F=eJ5+S6xzf|HdgNDop;8oQDj+3MyubXcSwvS9(-u#=d#QRc)ocsq*Hl$V4wL5)u`23#L!b=&~o7@O*`iex8F;;>-tC!qx zWFsggcjfoqv_!}8nn@oR52AY5PnisMKV7*28WW}54!d+9(w>*w)uA{NH&<6}q3~bE zj@94@f8kPZ`xc$|Iz!97RS_#|?d(;u>024FKBI~*Ptaf5_V)J&Jfh^_0?_} zq((1Ur9K#dkJJoz82=YT6@eJqORCo%T4Da)!IqH@)SEZeV}T}wbQuq%F&`S#hqF@i zr=e z?X1BxciJp#$ci&-BtA3$3{lfp8_@Mu-q=>#v}0fR5m_}xoLX}UUFKw>A=NW! z_VvkfgZuM6rI7nU0ki8{<98W`4k>4|90hDkS0_{lm&IgNOjaO@=}l+nYG5FcWW*3=DBc0n5=?>sYXc!9^Q@SVzvKMh;iJ=7;^1owKKEdY15*$9>L{K z%=@9iL4|BQ_|H~*M?H)*WOCx)SsA=2v;dMMChJnDL3xdGg49moDz~jj-84rSEE=6? z(d>$e>)!A+VHVzx!zj~bd*W)7E+Kw?f@cZBOkMm&2%Z7-95Qm>2$e{_5c|g3T_z1) zxHj67OXqMqKl0G~5029Yi6A)GE8PNRYdX<(fu{aWZ2I{;|0@M-zDF+8WWafAAC`rl z@t~AS+8rArJvg{_skwyKZ?OVdJB00Xb#I+&V=u&ckpuuk#j!F`m2!KgEF^s0E_5*d zxTOzV+p3?apJK~f{oZ7Va;~J#I-W02HosHJi&6NL_?yu(WO}Oc$BIY_#>l?h8XIF+ z^kKp-7u8beHydEek8C6@*0k__)TjIetx6iTx;%%_@N$g?hDh!p0P`(u6$*M4IsGJ4 zd%}aJ;TsIc(F$(oQ;M@G^drPJgmeGiS7zAG9#pv5JT+c)C-gz*FVUS<<1t=d3jIOl z^ZbWYN%X*>U@xl<&r{FSl`vOIGH$VWdX=m)Y*sW3mt`qus`OXH`lLS-zDh0QCQ_>i z<86DnZUD6Y7^3Qhl=^B?mM$c{@m(2c3U0)|S1rndbN#}Mt7^XFC@}Su+P?|w zPa!TV4RgaR;ysqadJXN$ug^4IaAaaS8fN*`ERVO`)zSDVGT<+CwvYs& zg?6jqXpGO2K;#EO_XEsR4Vl^;SfMdM9CmVIB1Jc3Fc{Y`6aEtzTAc0e%a=rs55Ft< z&Y&6?FRH|{#o48Y5fCec*nBEBrZa6Og^SvVFo_-iJm^Mmv z%1*pjPBEBy4e`Nv#G^H{9G-8olKzsl+Swuh7z(c&1~u#~=zYxPw2%WdN6o@Bb8=9> z;&a7d@`>}nW2u5hNAd*GKsPKTwy4ur2g6ggzPdlH>yrV2iZQDj^Djm4lmq-0j1)A!` z(muUDI^Ny_(82_)AgK48LhWNrm=oXZvCO3$+#=9@mli(L(G}AFrc2He3XN;i%e;%& z7ARe{C3bF9Vm!sT^2JuPd;IvbkiD>;_;ZVR87;^`ugCJ0i4Sr(0wKmPLG>6yEWIj# z6E6tpfIvOW05>ZNT!p*lSQ?`VCVMz?6E#Jl?r;kV)ii)r1jUM$2VX-C`VLv?gQNo!JvV=y>hBae z2Mt?j>9G@#QIXqQmN9(q5_eI+`8A)c4O@E&-)YKP8Jh1`B*8fIiharw_^Q#~3r3t6 zWX#Bv{EKI1IA%X0kYW^`H=YQA`UD`6OuKD$@&~{r+~=aefd&58l=Pr|+mPpqe9qrLRXxVZCja$QH70lLrEmRt}zFw#ZzD zta`C&gE=g$n@?>;HzY2C^UZUSxijocQRl-{Z)`8dQnj3P`EHHA!#(HXuYpS~$hTYY z(f~odSRVc{ToD{rjdr>!1_rc|y^iLQuuTGOILbzAkqy&`nxxWx#y^EZNN{JhtxmW; zN+U`=-knbszra$1HUQDOH?)8|K>xoWQcXo=FawETu<{l&*TT5^z3A3=WPX!Y70K2g zD*WrP!O%qdI`gYACzU{b?w@LMFe{sFy1od>T-g1#kCua@yvpvyI8BjxqHZ5A=Ul)3 zT7Wa=n`?Q>&*>ACAFT$ULm}n7E2WP&^ADK32vZUy{e0?cOG$^A4Wf&I(ta^PB zo&`oI{`@j@l7(lfM!6c8{ImVK0q>+$*|UikyG62(EGY7=vZ5k3_am;lm;_`E$f48% zXJl%}2oG`#`D*79+I}O8;^Ag3#oJ$n`7m`-0?3J{= z>d-4|A_XeCKftZ>v1S_8$sq^>lYLx0;d5@4VmUYkEp&c(FTP9>E1p6?75XB{0Fn3b zM6!C3%xzS@H6V25c`H-!as-Eo&8@3sjfjQmA)`#vTmFJYLHf|>^h7z$FH-1TQc+_mL*OMQ>P|e7Qe#!rEHuiUeZK6_Zm@=+b$96H7I3CK450z*I6@@|YsY@&Kr@&tlE*-#;*1Zb z7rp(2+ur&&Iv-k&EKw{^9D_l#6+ARN9I{F^*Y0(`!Ke%P)svBPXrItQRT(rTO=3se z-jN*tO3jQXXJWD;q?jVg(8;F})3HS5%I%Owb^+49Yj>n#Tt$5~*AMzmEu_0fLDOmd zqNYRed9ov-#3^Srzs=--s*FH*MCI04XG~5Tpg#63gDQLoj5o0^^b*IL**qG!f4!NQ zE0xv@W$rl^R29-QHTBcM1kRKh%I6P2lsa=imXQOdh1-j6%pX$o}A3?j-rzR1g6mdBHX<+_&ycWenmqeuNN*> zUq?_E|HPgxS=)v@^A>jLyA~l!Pr% zZYvOo6={lv2-^iX9VTi4f?yvfJ~LL*gg`ch$>B51Vu0J?7>p z+~lwbMdQzWm)}X$nRD%$5Dpc zx5G)MbJG!mITmsZ8#19wjR>Jq*!>Zd6e}8yiv*j%A_Q01mb#i!-2Yo2{a#u80sNn? ztRbdRf(Lv*Nqj}GvR+pbVjP4G=T+2#rje|=*uK&KC0LMVOns4zfzi#+EO{-ME)M&p z$kZz}$04Dz-R-)oxRN}MHS7zBF!i~r%grVmTMOUnDj5|w3WiQ2)0_ewp2CDLi1@)0 z7v#hJ7oo~z-w0X*s#k|}@sOXTdx|@xfq&OTEeZsm=N4^a21{KOp{Ec<3mv7PS_AZR z3@NA z|1EM$aG)fh;kNyY-sSjf#Mg3e4yty(a20*KN~JOeo}nn93!1L}i=wfTKV4tRT6z@M zN?SoK2vd!k#Wy%fZk<)6;qBVPKM*rpfQ#eeZhOEAK>Go^;Z5~&=iz5@y3n+bSxwH{ zQXi;%kP)XAT(WEweDJ(UJY)O&`yE!BUtXWi8_T1B(-O)BbAq{@5{}vw8VZ}IJ3ckf znAn@s3v<&=7nI!KYjwl%YIgTd$5lI`oQ|{ZdcCaEftM&LH?5qQ@osY_oDM zul5l;W&U~YCymMno=_?@gwJ7Rdc&~#9rX2@+f-jHE*#rP17-3K zRX8zLONC>kfVRt@Z+M93(ydbJ9RGfNX^C)R10+*}4@>`CFzKxN^=1R`psxGRG;G+37+@q6CdC1%4Nlo29=)VW*9$O9HdVqN+1CD0A|DQsIECWeTx<`>#}ab7?8tm*J!{*~V>4_f74g0RP=&^} zeOWb51DCeZ*Isr#$ zzB&2!9U1V%LI?n9*YlT`ikGFNNA0q_A+dyF7mRXJaNXj-z%wH09)G7TG6-@81eqGu z{_mj(dwGdb<+?w(>eujzA+q9!GZfi0o=CaJ7%NvQ(@>>R^<3FNu2s=Iq1ioV!=6?% zR6t#9st1tYks>}Ped9&(`1zGa-a4Na^M9`#{YAgwli7Ep;z&Hg3As%>mMnGgbC)uQ z;rzKaAY*$q>{MdZa$G*e7<-I*QyAC7(L*#br@z57caFb1ub~CC@Z0_=Eoi)l429S)XKOejM229wkg}hjH4>C?#yH*;t95V=FFbSCD`A zWc%&I7e8-=i)-tz8lPlL#lgTyE3-`TgI1hg)aL&l8yy13HuZbSiwb_e@K+`4rAiS| z_*|qOw2E#lr5`lyC^~wxM0zORbo0cRz|?e#;z_|HZaVFM76A8(i-mbHK3%8?_W0QF z>6M;^R{sH+G(E`|3CMY2p$nznDMG$~r?pyD1l2JC%!wQc<<;(wsRgYq4h#-Uhu1}} zgF#ArR>d000|_Z@KMzb@k3D-xD9j2q*4oLQkpd)iyuuqVoUI;^Pduj!BpWII`&hCt z&uj}ZAa&fP)0&w8X<7LMLZvt7d|cIQ1Tp~PFI=b4=3TD0UR}lbRNTkNaiLq!0V)qZAtKyf)4&Cn3h=!c%2ymGq4Mybkr2N*)zJ#bkNx6(R9=d? zT$m-qf;OeGVt%;&&+!+?ImU=S6?qx+#cF)NmDR2O$j;am14c1!g zdJGp+TkL!CCwNJ@zvzw4(Xb9_)>lT2;}Ddf9;8tfp? zF1mcxS;ku;NjE{N)c9I0U(I|W4Ce#MX&^Hj0B}N zsP}-2o<6)>rw-QXE|A~OkjmPP6=;R&Gb%Q|Wo-9fJuBs^k#Vy3){c!_^e2eim-(UuUNfXJ~o(5u89Y0{R(QAzNyqb8|KEWRXA`RMJWyEj)^of-nJPcU1gTkWMJ>0jNkpfUXrA-TTJDY8kT*vqxWitj}C^ z*#1=&@-ojt_8CdWFCvy7T&>GACfh{;s1#szG>&8a8%2tHTQ&m?ixu%anuK*H!|fjj zJO$H^pbB1rhS*a`Jo7P7gcwfP|Bm>mA9}jrO2qxdCGqhlu*O8u^X9zO1>lE2E8nm! zH_K!ue#`xDzq^_NkZy2rFrPr$*WH#D!(p&EzP9?$rqi`qig_TMoMM2NmanFFyXR-D)>B-2-%Aorx_=Lg-M=&#Hn{(FM3w*gAeT!{)da@(MCKv}Iq zp>aH1uhNL! zy5C4g5V^#+x8NX(9xR3JeP59Ab?w!sA9quBm+IYTiQ@{9ep@+MH`F&UQDn_l4kFYB?$qF4Y98YT%cfj0sI! zMUyQ6pQ8tAnAb!5vlSnL(zJ^9cH|o6!Kn{I-*r!-Wc7`}I9ZJf0i#cOvmN-bV*o=YY_9a+?&xj^8o{c~xik^$U{nCR$w{bBH4mn|FLF4ZY38J3?~ z&aA0OMWA-|dj@m2Eny0=M|LV2#QCx77B}SG&j5mjfY73DD$V+}Zg)Uk|*m zZFkT&<@lXao?-y^^w6ZNxUy15ll4VYRQS)SLvpeXp5E-$fD-!Uyyofy~z(l`FOoUP`?yS=vir$#?`ELMo&;pY%BnH zQBknvO=?T^PkdcgugWfny^vy-pN^<9vplY_DG^bb+lhpeU8y+#qLP}>lWR6 z&$m;~?o3hIVSR(WU$RJ;G5Npu5me0+$xKTt8LdMFb9Ab**f62MgdY$J(ee$?Q<38L zwn(H(w6z+hR?OiAMu%<7Xje$gxF<1h0ci)ft_XHUl759Hf8_7rax=3#K0Eq3gUhBO zx6iLFpJZf4$S;N?u>gI()%B|E*^+l}QX)U63#DxcsQ;H1z=Dyd_raOTD)ED4q_8@= zh{rB4*|)VRpZXfLKJ$(j-2=i3@Kc>^lzo4CzEqGjj8vI}!H(4*-`?hvvIpTznp)&B z;t>3oYd+SN$I~?sI{bnVor?c^>Lk>M0h&NKDiJs-HdhnB6$Ks@VIp;wb%STk<&WQa zkHga3`P&I-yqo5^XlG(x@tdW5y-NPkLQm?4#bOjP2_A&HZY>cgf1r1cuYHk!eMs{Y zufIc5p|-xE!DgT8zu%Al3!)EW{Pk2**M=8Go1QN$bs}vBavi2tSg@N@7*ZtR<+?Y9 z7UdJCFOjHkrvtcay-Ahz1SMR%qaux6!OGggUD3W&;`7+j2J|*|io6CKtPMKR!y=3u zgi?Y81qB;dG5;5zq5II$$%In!^J~aa*jfVaa6Vo8ZuFKwQV+`n=B{K^P);2B8l2`^ z19@Upc~Gh#O}aC|!6CN4V4K=2}bQ~DbVuGFB*ldxDt@Qw_hg(+^&$O@btdUb8r z+j&p9|68-#1n$p2m9u!5aLG8UGjGryZO?)rXCcy}Y7pN^FIF z3@zwhq^XgOZOh(mHZA;WKB}l#l_Vt%%sW!0>Kob>k5#A8geF=>fxTqJ_GRQ*8W3Ti zq3PA~l!a0MJEPa;KnCAry8vFrX+UwAC+V5Y&dxQ}Izzb$Vm<@iDg;rc~RkrJ2*Bq&-GWkYcaGhot~$C1rxV zIa6G2*tT*VZwZO?`FStj+s5(AAH^Eo(6a*rIzcEdLVdO}IJfwvYWXEEq5obXi0Hoo z=hnf&L7)lwXr1<>5SN$jO(NL7c)zYh7Ba=k=ZciwC|A^N)uiZ%{ry_qmlLICXL(|Q zhI)_R-rMzJ%Z@Kpw>fQ{pB=xw08C&Q>RkmD#)xKEBprd?==Xo`;B&Itf{~}zm+^g0 zt$|gDP0I?!AH|lf@c}HQ?<{~4^GU}JX@?DzL7m9ZQhecY=;|; zB-R!>80z$>i&h32ks_B<-q|4pF~X?oY99^NO*~zq}303|y#0Sl8=ha3FqJd^cJR zF8Q1m@Tb`S?JZ}RpZVe#FMbLN3Pwhxv=`|3jigYEwMA4*Y;32_Op7i7!4|$ol@NfD<*@_0}(ggF_0lFQ)^ufCY3CZy;<(NBIv-ko< zUn8S34F}sr)fM&>0~3YCuSrR`$-x~bPB0D1ii+URgr`XV_glm{Z0>>i*LVu?Zn-$( zGjoHrMO$Uh+k6`N_FUsp*7a>KE0!?l&*|)Sl9HYBqqyiG%vS)7|L+Ev+F5IJ10*AU z0)Gm_A{t;ABi$@xaEJ}lv`s*IL$SeFB1xXpx!Nx<7hM%PmEXR|QwaUHZDpZ!1a`;&g>5w)*2dKoJjl+`f~ZV|DN%c~$FZ5dzK6LvH4IGCv5unI z(|oyBl<|M}dtd1#AnPM1FF$^Oc7X0*8h?AdFO=IZ;CoFF@FWK0XJ{Tr?tqN8fw#Ae z1i)l}QQEzO@9Gl|ANhZ5y=71wQP(Yuy9Jk^!5Q4$-F{`nK&Fys86^VV(yDPOs6ZO%Au&Q(r& zUfyZ8U?}Bbsb*jdp$nwt9)L6VxIa#n`g~q8q=^U%QWvjdsn+7hzYf(p3<`RFehx*% zoZ0`MxF+l}_~B~5@E^f@bG?jnJ|^aUc6Mi*)mU1)M|hzC{@lT&$5EJGH?W*cmYW1x z0yX3L3P8%;lSP_^=8iJYy2Jzr=47OcX+5v}NNH_t-B;l}i5iu?%w^uiJRTD95=H z;HyPJMI9R%`OamFEm5^8tD1`x{6CQ{(r|{bFAtaMnR1Mdl~$HkuOXRAsk3nSz!6ZT z3th<(frt6;1EwVw*W`XUbARszA?KX|{VJoVln4h=Q568ibHMr11aOxmF!6J_*pmKz z^1sQ+y;y+?zzysP%gWO;@1i`wMcbk*lR%?tJhB*yS%#Rwj%ra?0wLvpfD0OU6vZhC zbV4>LW}(RS-o_YO`p|+4<>zEKh5_P*GW9|L@d6@UgYJMAM4*HMgox8a)c?B>qU=xR ziURAC+oZ7Pezs=;$~>?b12(mr-GGT~7OxW-cn)Y3d;ujC^8@dHE*%LN<$n@Atbd>W z<+~LB_osg;+kgJ|FI)eAKK&cv#h^3ym59_Lby1D^@G6%l!V2LQuoM_1N-2XY5=iUDvs_lIBZy@^mv&S`a ze00(1LZ8LCoKOxA@&A6WKR3!!tHDyB_rJ$4GX*la!*YFFt%h^7MxuX^;=c=EvlvKi z&MwiJ3E$6;mH(F%1D6x>X9>>*^uKemGFcO8@$TOhpCO`u#zEReRa3UrEY^?C)q8rK zw&>1!+TPlY)~$K{e0Vw10QBeexqL*gwSA*HtozT@>55CP!b$K8yK-avNpDr{xH~-z zd~13*E`94zdxq|zmQ)*tuZBy9ZfHNo!3M%sPE>av)m zt49nB+^a3i3~w**@Xcv2q0ocB6IDgz`_E4$Poh+M;Ux6L3!nYg+W3LixN{ zs`nTfp=#}tMNONb+vsPj`RZjQ%BM_l(Ip8;VG4u)<^^eO_$t@m>DUy`AW8VX)NQ{Q z6DhkBSy<{tme)9%$4d_zlp#TdH45*5{+ZXL?rQU8_`1rQHBjl_q%501#=ZPtsRtmX zWa0bp$=Bh)^7pl|te;rwBRMZ|oh5FrCK54puYHW1s81nc@}5-MPC; z`&gDKMsLt)a8+MzfBb9mjn4OcwU*qm>1a?h&^RFghq>>e9rLIayxsIMG!449fPoq& z|Gju2|NTQbCkr;n4i_8AI8-a_gF)`|edbAT?u*}0D#-%i$%mP4TWS=!Sb%=^DMVUR z4!C_GLu$MW;bXc+bYQMIWeTsuqq8oH^Ig^ei0}6j^fT@M{_G)Sh@FJXzA$37K@u)H z&I%^q0eRu=R~Z)Q{l=u<<>~mosNX7=1pSlxhd(^%QV_tr_#?_!F?!FbgT3u*M&I)y zoAtl-w|MjO?hmNH{R4l`!ASs4dVr06zNN0l#KKA%#!oWS=16Ih6-Br)$HpRe_{rb* zH?@HjrW%IM8+jk)VS2}=2#j1M&HXtSR|yg@cVQ>JnV2~V!U)NVk3p4-uf+^~^>kniZbY;1g?Xy!39-bZd+ZUVae-aPmy4@dj^xn@1*A)>`kYy-we|93YGc#T01)>Ysp4?Dc9=w2>FbFjz(sT2a2#Ve`-W zD_X1Vhkx&$6>4lr;ByC^6~Q`rb@ob%o&fNciYdPVLwOw2J?CoRPPR-lO*y7o0Cs60 zgG~c)4u3$<1&nBNbTsPgS7a0vp!YOyYF{4gR_M#~GYkw2phOevZu2;8`#4?Tx#qnO zgiwucIPV1smPEFuo@PZQkUHK@ZHbR)u}0q$yJoYhWTyywE$ww~sa`all*W_aXAJ3# zrkfsWne@iI)i(wGq72bK6H&n}69I%f#foY8fc;LjJ~!aFQYAN(+ znLM2UqRiD}}8 z#*BeT{Y1nEn+KgpK<~i%p78e}PS5>~oplE=`El9mYMry&G7`hi>(U zp6x>37t@D1QZ@x0#Z*waK{HE*6w592MP(cdT@Wv_x{yyA0II$Mt?CciD4t7eVJ7zD zQO*L5t-a^{233|D#M7mL#WaM~bXNAZy1U=n$*$oMa0^*)bs0uvYlc0J%6Hibe( zv7{6Sfx@K2>V7)oh-1A8%UJTeA08TkfgA2mq!0l!p_z7q5;DD zigF{9oB{u%^*6(Jm}Yvd_D3H4X1{$7Nd7(MesH+Px{1j6?{ha{nXGiN#(&q7-1vvU zLklJ=70Sd$MMrO61!3ToiAD63^~6eq!v9Fl>C4!uGd^A3fj)WFbNIt?`-|4&8s6j9 z-{X|+>2IXp%M0a`HNl@dIA1%4_H6{7lJw6GqZ*ZvbG1!=@j0ok;&0aCOb8iXM{^7U zWQ_a{P1tJ>GF?ulLk5ghVX|>2(8QWy{}#$*&p7FmQC%dR@fA9(DoX#IsAkc{bGJK} zkegXmQRVL(@Cvlqa|%`J`Ey}MTJCUT)xD3NR?V?Ctkq`SC)zgZDpi_J_4}!H-~06n z4f6-WebNI;;4|RgB1?0q4%xFqwBwq9ZHzi=)&WjrpKOeKDN$^`~hP@)oy91?IvqTu#St%1wcquLX_DJ8&bOq z{p(+TC9hUl$xYr@)=LwiYOlu$ z!Mynr>)SPdJm=2Npi~8s)(+Rw#Ljo0==T-$?wQ*J8976&>`_L5Coxk~Zi5JiP6Z7U zbFoCHpbG`BP=9{u6lb|E+e)%RYcakSRg0B*1T<4`FmcHVEn>Wp>@1ItfiV84-Pdcv|Rkhch?y#5Rm! z5zr{&c9EAzk1(B?Yl$^d9dK4&tW*uN#Q z6uOP=wjW2?_?ge^svYd2`WJQ{DpriYG|3@Y^|ggwr`nxGh%ANq*?gA@>`_Q#LMoLkjS;&VMIF26}`(q>gW;a`r9Gg-t;R%ZU(S`lwCShCc)tOn1-rrLLKg; zVrgV1{t%k)_+5o=Rs&#R5*?k6bCXy9*Bvmj8O-T77Z4WcUKW^SjERDLN0?sbWb=V` z*-FrA!H#x)itBJ;nQcC6gh_dsfuyR98s-FySv4-)aknd9IG6XOr9qO1`F;oYIvP1dlj}(v0{;{XqjrNbTLyzLXJMLu`Ke#GGyHM_ zBmeoj2gPB{FgKsh%3Fgc*}3xEr}uBXwzHjgMa8He6%B5a86=kt#KfQzW9eZ=*Erzd zmg{kW5GEhA>{}Vh8WluAA3{||@$1gBb;oDIC~0h$MLzTG>Y=-%X`;oD#dBR~^6!Ii z0}q9~=Cenn@Syngu11Wsmj5-?bT}8Fv6)`MGl&X#Cs|rLQaem4uAAU-0jsqSH6-!D zEF4s*TaizH_209*&;FI9oO*&lXdBO4ODh~soi$p z7A#X{yTPJbu8`}L?(R3hnd-l1ktT&eruaWXL#CWsUaZ;W>3oA`oUaSU?&1b4}*^xT*K_S@XFnnKcQ8l0^@K0!hEmP0<`29aB>G znNa(~?;1Kfo&llef6p=q^`El@*AZ7O8wlM-?1q#pk6Fg2q<5~JLPewM9!NX_P-tEZ zeoEsuHW{%LMy+!nq4h?xrb5`t;}wWgNOoVl2h7%M_f7IlP&?^nmVO9NV(uOn0UZ?| zlt<@C%=HnMq(`EB48}Ai9a06nn?H+^3z$}aTl5L#KEb43t^fAD1C#(CuI+4CH&ybP z)DwM;8Dt|@!eh9%Q$qNsswQm?>0JwI-42cxU1F}In)vaiASD{b3SPX2U;o{WK?F$H zfN8yl$wOD!UljONq75_36=_^Z7S6wbn`>G^6Ct(66s5^6m@~HAbe64zx4|0yGmMeT z@j*K^V^uRe)Kc{biVs%C$4hs83=Tr7{(<~0Kcv>0s+|MYYX7D4TQDUKtTd{ z#`kl4Yy6*X?|009@CFTW4-EYk!ND zGX@42lK*>oRowmN<(Qi3H^^vHIST;Wg{=tUy#T2I0M@Q~ZO5iE8%Sso;NgX@0giz_ zME#oN`u<+{7}+Xc3=j|y03NJvnOZ(zUzY~j}>Wo8!%}lh-=^I@(N3$QCz6hb=vuv2u#K^P_R2-*X)2E zs~_=wC?+R3d+m6U{rJ$8gl936{_Cj`t|;>G3KuIMp7N}Q>9fUry=+#>S znpR%N6|roUPIQsL*XKO(P;6{$H3m*et-T8gO-OqC<*TMZGUSl_;5Olt58zx)8I{zs z>+o<11UcfT*q%0=pFG6#WqxC?B)&12n!NL%Z8XF+j3PJH^XTvMdH6X<)rNzc+C5cPZsB}(qUF#mHDeF9e%)fq&WH$2Owqwc`(qS4YTP+k+l=f=LyjDolM97bM6JeYuNod!@+&*05@cE5oes8 z(8e4xV}V$wARg)&CV>$_hFME_~O&}CC;4$MCdcwS{Lz~=_k1`UCR!Zt|C=e zhVF4!XuT9zw+eVGUG#yz$>LGOq7*A*BZ&-E%MMTHmeTlKggYxTS%ZUOms}(Vl3O;b zG;;*-UXk=lMVoctyH(`$vN8|<1enxq7@qZlRNe8zuhR+yX#LRG$c5gdE*oO+rd$nI z)zP%|2o3MgsFS`cwXi7F%ufCJRusXR9bxnMO_WwnSx=l}ou`z-zW9QzUDSnH9Ajwp z0HxYSj)U@QpgcJ_=|)bSW0MHlI6pt1q6nye?(^||gKELbx zKcJI8yJAxN)yODUN-U?kr{$1elGrlUh3q~!p> zp~kK`>fl=&^mV4iQt-)`cpdgS zB|{f3T~FVM%~+7O`NCsC3!+-9W>gIu_VCFoQA0XR>JfCP6PHl*E!t&g3HUIDzXwJR znIATaX)Jh0haJEBgYVt#u@YmYTJe0psS?VYCl|?r;s@BuZx75Pn`=7@#|VLlL5nH6 zBXRp9$wT9Ehb&;F&y2)og1BAfH4~rum<>aZ} z0hSuCIK6T~l&}Mn4#@JT6e-Eca0%fwa1>;7+8Ui;~O- z>W^MmTdnaYmd>HRV-eer#z~Sa?6{W)bufG+$h+6bf*PyPgl&{%q2jD(kTH1_XXvR{ zlb%R#O@&E~3ceEQ5-Tk#0^C&YH+SVRY8yGK5JEgD%_0j3305=OrQc8(aDlw+_S(1>!eU_iQ)bGFwl^xoy ze8CR0pH4Kym1&Jdyx%ecu6rD6?6T*5mHd7UZmV$KhPw@FY^s%wdXENk7ZAAsIOV26 z_Lo6L-q%}mLCud)B=Q#;vJa|!3lXvGovVWbo9n7XyMmS8y!|q%smVRX#78Fpe%m(5 za1SU$u}Zg-Y@13Vu94vcg7b3{sA!5FB(k(hG$>qoQb@w6=(H-Wyk2e-V+CZny;&X) z9jDO+W#&JT1e+8<>2|3&e~$`g(2I#d_MyPtONbB;$H4pvKxelc;mip-Qc_{a@9;+- z53Yp0QtRhKAG;DSZ@aQ~Z7xYCX}&F_Ij(Ucw4>H)-A9d+b)Gw4T#7BfGcULKLZkFY zL#F&x&sE5Cbco}nwA7st7Za{(R-izkP^}}hj9I6QBqaB^Df-~v_4!zFcAuPWkndoo zMR{m?24HkXu@0g^Kn7-J!kwFH(>@QGUEO~pA2%W&CKg(w#Hzv2_yVDTb?}!ntFf<4 zJlF*ztD#gY5I-1O^|ZN~kAsS&fqm%CoM1vou&=zQ2R+$wGY&Ovh}_aL58|5m&jd5` z9UW^?wR+u39dtaVe1xot>@aEH;8vtPb z!x=}%@BO}t8B^W=V8rX?!H86Ax2<+?tqu;$Ly3$ToT`qawAQI`0{hqsy@rwGO?~CH znu|gUWjmH4TO&R*f-=nqDP9z(L#M*S^R~~dJ?4D`yoyh2VF><0AT|-FBGS-`BSB^O zjBteP6#HhBR@!-o(@D0WtU^u~Y6=p*(0MgYm|8Q5`ytcI) zj2083=1`6=KeSQ(g1%ZRSYh9#;zHKyj?&u zr^{eI9GCc7L+)?BW~~^8lc8ybf@%cD_cR3fPT?gKe}Of=p7%x8VpRA=D8kuXpWff{ zpQV2%@8MWDmp;^2#qcIVUjT$!z)H#4Q*Rf(EASzJS+Nq?(X|LY}|K3s|15WhIVr28m3x4QmAofNHJTw3Le(;V7=c!kO5yjp%Lj ziNS@ogrlluTsN5+9DA!uE9yM#6w#rvwySjbyK)C*N-?naU&+tmditQTncywApGFHL z5J`}ru%goIM%LswmK)O6p6QPt)ML8Hn&f_2_JUMg95Eb5M*%0;{>v>Q)jXy0tH{Xt z&weyys?g@!2Pk}GI5?8ooBx6ql^KZrL)v2WsC};YZk&d@Rny>1_}T@PPf=g7H4w8p z>kQB=yNXYR5)!X;#O`e*=z2OyFU!?&zgU$Ri5X)@cS=xvf|ZK6nAy(_Jo~l34x~y% zcw6JaQEOZQ2=JnXLt!vD6i~a&$!lnR462$mzWE&A((-4*{%rfi*K2vjU~mgse$>B< zC2gZnE+7dR35i3ot2ki{Uc!!`ymnOeLc#6cP}q1hr19g&(luk|1M7G!UyRsLS$y-K zA|C1bP$FgJAk`z-hyU8+CU;3=bsrMZtEBde`+yL+!+x0wzn))+c*lJyw+wS@s0>5b z2|EG}9}44b1Q8U|RdS;74D1GY_&S*rvQeYS+d} z=;}a?FCR?cF<}UMfVQF0a(es$T(!rr_?Cw&H&26KN7M=l3|qN9yx1XnIE7C%JAV!! zm0(f0E(8vDqo5=n|7|stFxB3Jl#-Dj=G{XbX~>EAu8Q#A8I9|+s?Rp>s%#ncQG$vR zY9v9T=C%lBD&~_wuiL|H6J^um(53ky8#9;^Z2FSf$vDb0)VJb?JK`S-nBIiSHbA~T0xiI`lJp_#QdY_suj6>XeDDt_*CGQmF!$Sg(D#srDt>{TgJkcl3ZDOTb zsw%7vZWEsVVj}x3C~M604$7*234ma_iDoQA{_yYsut|mp&H%y?RE64Fu`XP|T%~S2 zCfIq^lC=(tk28ZrSoeZvCyNB9=By>GAzEI?n^W}s^DKO4@Lr`>3#yh5{af$8+d`Z} z^A@$iV$7-Dr>8+^rMgOK#o{VElm`heuLAF@a2Fb9f~Q=9BtBdl{%CbL5l!3*LI)Tj z==^&rE5}W1&+P3nJ0^KBJZRBnuJJv}=$~rWeTe@)z3E74CBWjSQwh=;3pqC+)(U;* zOR8(hT1u$1GKa2I(6cJr>fx{!%Dt#8%D+E2p6J0ECr+4pysARSIJ8+zY>r5@A^tWe zg?&)V+GgwJvq|yyQQO}LA96-cvq?!M4=O4jiX&AVkvH!-PO9zg8zf;o{PD7#V99u} zJv-*2Mji5p+PXr_KRg*B8Jr*^u6TVi1qZSeG_{XYz&Yu@SafX)Wlw>}-9lnY~9@ zYN!Z4;(|{PZ^Yp+putI>*{qyQY^_ba;rzKqvorU!GhlZ)f?aQgp(hj(;}uL<@vNbw zf!_Rux9xyUL41u-bG|8#ll#5_x(&2&*5s^VdP2!c;$1SnY|dD^>(-c zhP{LS>o-Dx_9OADwns`qlA;}&TAGfdfNA0JeUngR?v7EbUIWxUqj>PE+JBQf(ADx%gbAt%Ot@LD-B4{6Wj#XIdT zb^*#j%|AFdA~~3bRp3!mYi*qKWe$vtDZ6Z|@wc zGgZ3Qk3aVGac&hO<3wXY3W?=5IQ>oACO4I9*$riF7)Jr3lSmAl3Mh#ix#m_|Dzam`I`n?O#2cKX4& zNc#HPO5V|-bL3aVpd+?j^agX!0?zJ8!Sv2;z%V=hjBVcvm2*CTk>Tc04*?y%(Q5wThkYN86Il_Wo$=bwVrf5Xez(L%1(W6`tU>9sZ;Q=M|q`Z_7ZI_cgGoln@8FM&^| z&1aX1VitMz9|u|Fwv9+2pmEN4*)pb$3N_D$(Pj{Z#s4e)1r+YPz^kb?}UMq8Gah=&QZY< z;7#EL-eieqTvOr^e`|E5X33VK`!@A)iy$%z^<5_WFm0}w6PtLrQkOjQr348_7kQ{G z`NRhk2Xi}T@cOA4N;2eo(1G0u;iW$2%%N@n0GZZ-TC}Bo+=@j=okAKl$(lQysdxou z4i0S{+mjU_Bzv1qzz1+aDWeooH-ul>C>TSDU298PwAEFjOzk$5ut`;e!>+4gH5)}e zN=59KG;##XQfOT6=hk`mky%vTe377605V_5)y^MF7#eF%vnPpMP3elR=>i&FTSAnz#0?9X`5B5GKW|jiBBAr@Z}7^b?jHwE zrd+NdhBl&}aDP5lCyl07y*3WLm%T(8VL2(7Zl9ka89I~NAA4b`#jgUK`5#`2#!rZ` zu(-v`_GXg^)huvK{x)H>@JTLI|k#9a3PpM*h3J_dkWFJFk&NJ5y~g)Izr zRLA%ezZ`~TJtG;w_-gP%SJ7pBDWpm8KP|&He=XEB?3y|-)!Jnzr+H5Z&}TdgF+)Sz zn9Nx7?O{`Q6Ngsp*w&>5^u3Z^hohg3|pZe>41+KImn^RC%JVaW=ma zFv^tg3r8IO*{A-mvcV-@$gZ;iBO(8^nKXq`Ir|YitwfgTmgHmby)Z{|-LKz5na@6k z@}t4Ra7yF|o@TC}^O$04QymG-_61rqHgz|jaNfNWH>xc{tPlli#ePkK$$O`WLxQN> z#Gm8L8~CQkdNuquDVycYd-q{}otT1_^m@bR8U9RJC?S`~jAYitZfyV*)1+#XjwBAqME#rJyTp!UAqw(=-K)0gvpOgVEGWARIgLeENp&LM32XZJ|< zTdCgYTIZR-!0Wlb8pCA?oHAQ&COS)v2;;*+p!+$cyBqL^AG#MrOhy z{c71dRSNfjh2V>XHl@r4b7!W%Lk$kR+NoL0*U3w#F}uUtI$sDreDZR83YpMS<$X?Y{RN=b-qwv~xTEL4`GB z@LrTdGx?oP`+EkumEV23E+&7kPyU`g@Vu@;yUjJ(it$n<$mD;9a+_6xeX zTMHplV$FT^b|o6Z9c^NI`u)N52L+XxZQ!=cD=Tw9=GKkqVxl2=o%& zts-}U+bpt4(Td1S`E?>_U_nKE+(lijv>ubXG`9h(r&oV8Yt~HMo;LRcnpjRUxG(|pZC}1bz=K=xi3A7d$bap<7@Yr69L3zl-JkS`myk= zV}U8e2~Rbt3r(HJm=3aPm=Fb#<*jmW66Qj@z?5Tdt;*SVp&#h4(&@STIy;vN@fH;$ zZAJUgKA;!_b{PzVw3%B!6F&eNj+J-6-q+=j-TaZ&c%@%MO=88he3)VSs4Dt+@S*t` zO-Z*|;XsTi6%7JekxLh}ksO}o&3(Hh&^0h?e=Vgj@(yqwWi-l9J+fmClO}{+s^N;P} z%rVo87oH~gQpSE{rY1A{w*xP9!BF)0y!kD}qU^>sk&TKlyBoW>tX0Qt`AlG8Ib!ZVDQLm_?>2ft0HEX*!RJ6IT^al7GTNrzlB z)0I3?w!&{ir`|wg>Dp?K4|UJ_5@y zJ%98Pnoq;Yzl!Io>zmfXU}W~%X0DDi2 z-6ZpdqaR|}AGgTJ2b_R!-yPB^4-U5tyf?t`&`jO?SU-O( zMU%5RPH5c~GkJWrWn}5k5cFgzrtuC2TDz%Xb(dqsq$D4Z@-(GHq^_Mr*B!nM*& znOZ{!1Zrdt6}rfjSFUC~Tb5v!oOT!^hRRQAj#E8eTz&z-o#d!<*_LqxldOv*GmoG8 z4xeZPedt5UP+cqMBC2tfOyGx7rci6shY<~0_>IhZpZg5xG-yty@?krTf5xRS=@w+h zh?Za>lAe^)Tj1Tmvuav5^00b_M>$91GXoSPOrNDnV;ZT#0#sOhR3bgjg%(O9`DXpk z;_(qw$Y4Nt!;40&G^1N}hH|S&IB&jLvHq7xG6ie7WPn(e5gx2IAW1rjkH}tszCecy z`MLNfU7#EbqL9X-%!+?Iuru;aIRiyqYqS6<1saR_#^=9{mp(xd%HoD-k7LSJ_tUo%Iyxw>@_HW=I#W<#Ee;YF>~*pC74Za ze49CAsAS$uU9)Kwpmk(sZO(&Ec(`iB4@W8bL!Q#GAR9+gfRArL?*ZWI{aa9puu`F4 zZ4@l+GO?6{NA!2XiDaO87%0Q8wSA5zJB?E`7Y^9i3L0e2QyR}vJQ)>m$7A+gsqi~N z01vO!n{@sPY|Nl@tXGYiP(!Y!R{3eB3^BY)XZ8tdGVO&iyP^OP=;A7qo6Y%ODM$^! z@6=ErTa0s4sF3vQrGvHP8Z;mYpUn@eDxCc1!aUfgGGzDX2eaTvkSKbaPPFqVleGQB zYG&w#ELm1}opC84K0Z)cX7|a;96AhVgjtyPmxhO|*vV_PSma^BgRBYwF;d?n#g51r z&|PY6U0AM95=H8)X_yr_ulbnnK9s!!d6Z7Xd?DU9R@^*@^>V${wYiziKPewT=!LJo zyaMwfkcg5rJ#)dQ71ZTrg$BfNTA8l@383cpuN%nxHjftM8~?Fy+{+$gw}&ao7x;qM&{dtlS5Jz)#ymy#W7_-Z!I)~SJU zsA||Dtj*Q(Wl$E0L~ob3nn=g>jN;q#6{avGyKtZ&XxB&49Mx>NGZ%Q$X$3sbKyaXB zBxXWiuycI(!tp>;|1n5NP1k|?a3w5X7?J_RLp4MN0cY17`C2Po{(^LL zrC1h+S723-$f6jl&j2VHg~9e|nn`AUUpjSKQZ5^Lvl?O;(!Jt^uoj}F2wMY zd_Gg!XCmgLAa1)k`mC5R<}kUdNaO80RvL9P1aib@@}1N92qpD|nx$|eK{@ja8=(*1 z!WzHB-`^j<*PMGgXXdC9EI0U?9BEOn3H1S~wK3c!3Z8*X_3*7~`iQ_+Q@K}J7-hn2 z0M^`iO3)%37Azs^c|sZ(_y!2YvW*#%qkzhBX=!OD8q>f{dqBHflo~!h{b*mp{l(u( z?ufF_>)@EMw_Equ_!gCUbU$6il^edEXd$>=|ttnIV9Ce+cbh(Bs>Qq~c#P zUKAlKxpH3&gyhJ4Pyp>zn{WHOXtY`n3tyq_##q8?U2}!|V2zC1f^_n)d0srb`y!ej zOO^zZT5|qosGXsblA4MsWiMLBcfDo&KaAbVMt)lu*Mb`0w5`qT$!ve8QKwJ}kgr{_ zx5I~h8JKyv*~z`CfL%DrAD>0G0vF20mn}}7b~Q2Oj~SrS8$;i0j*cjmBib( zLPD)d9a*j(XRax)W@JEP>5pbaDLIv8usVy2*q#2|e%gW`37b|~yY55C+IYSwq@pwa ziPf;y=r4qpxc3cwRfbj!=5yOatLhPk({?D&`eXvW82TxNppj(l$dNC+~L-1AMuYE^@E{3Vg zaq9?mE!p$~v8Q4$IR71M*)OmlK_oBs569IE;}3I@B)pE!8J=fMh!{OUDI>}a^WZ2} z*(wj`?q(5&v?W|dNNYVw@d=PSYO(v*2TAdG(NMZgT9XT_dC(1@o&XBA-vQ}KEfq1V$y;)pvVVV}kpGLCA#D2w z;xnDlf_-c@01R*Gv`>^~)UFuW_8jcADHpggeJQpHPaQ{_{29T-z?jmyiZD;c+r8`S zOB1{Gy>5_YsPE_nf24M@tmS&&%fo?+F`}%vPf1+3rw=S+!rn7FHdaW0lmg=)?)Mi# zk|1)S(DKK+LAx7nSj2LBz2@kBFo~DW_pn;Bfo}ye$j=HRm%fftGaWBh(Fs3|#8s=go2m#P*1>kE35&~@M_gdZ zU)%9yy!P(A?5Vpc0i{H;)^zKC;$vt~`&i$mV!5N2WBeRNxpKN6t2UjFJ6jtbghvka zVZk^W1kAic)O%?~{`TaBaphjvq(1(Z6#CR&VG(V5@!+sLY2eN@Q~Ds}943js}!55WHv_%1!G zd){OR1pODL3=Q0}f~euo^OrQ(Sat=Y5*CFDG2tQ#l%~+hhx6j|_kcT>{bJ3hf?=3r zxCkE%gY+5-i za95Zr=jLO^bx}h1f^?T`t&x8{2WRm7HYh&leJSGrMwktgI#v}n9Zhe_Pk$b+n%-sJ zaB9_l&AJA>!e#9CxE3I}4MpAgW+LLzaPYG2&Toue=t{eqNKM!n9dY(5SoQ2JW5V~avGp3jYtH{TT9Hsl5-eLYUgyFh3xb-p1@!I z&cG>BsLIWX{wQetg&ygm3)BJDNW$8#rFP`$RJ4oT>e5^+q6f5L+9L45d@pp&e6<1Z z2FT><7vZLlJ(NJjZ(cD?%u>x?DM9|X8_u=CPN|?jEo9Zg}n4$`8*)oTAsq6}U6u{B1c zr=Axe8-;Nuv-$55yj!(ieRl^9S~6!q16K*#9@;&+=J$%C32{NbnI~20=30=c9dNe+ znmQjNXKj}74v9wR$*QjSvLL<^(Wnk4OeYZt`8p^(OmDta!shg+&JM!{I=jc` zy*^2fY3GZ&mGNh&Yf%=Vq7DPCK-&(xFzc4$5S>H&G#y9Co8aaT*9k!wRi zO3*lzm^i%e02ZNaEovMZ*Cs6;UG&d2NuhQO)y7=r)SPj9UJ4AD+K_>iu0S@%UJ{-n zg?CC%!56RM`eI7i3-34xQQh%~YGKdArFa0$+&b{Gpuj5Q0;afPp0NAP2?S2YrI-O? z4duZ7mnc+}L7I)(B!)YA?K(alVF;dwL+4cI9q7UPs4-t%03O=@ps(?O+9{_X7um_l z>6!@e*$X1`jYBG)JL6TYtoyuwCR(sm)Dqjygh>S=4w`RuvkC6VmNyyHtvPiBUeSbi zm2>7*EZg#65NG=|m?dnakC%KI9xS_VWw;$4G~eQ4;Un$rC**ez0X)-N&PfKr@VgRV z=Ifl~j^`MV{8N5C#2wMJZczL=)8K=g9_HQatOj@tcI{pr6P&KHt}o*g@pV-Q7IwkG zz;WnUctO-cuO_a-Wc9~8=jSNp+po&E5t9Blv}U9xU&))OLgRtb}CHM$a#h3yB@aLPR2=`I?40PIH2^y*C}3piqwo^{9DL z8h-W#U}8|`IwfO*HyXqO-}M023XGjpe9?8r04=enM+`?EKcRnEb=J53{gA$^5Wxr| zeVeHs8SyTBV*5D{map)%(0jeI*4!lr`uH`;g-fW=6239mmoioB%<49kJdP!ZCN3w% zT>p|H(f6OESFe)$yx^t4p@Nm8%=No_796y(L zX@2|8yyK4}waqEK^qy4EL84(HUtE=&!pRb$m;@M`}=#^-pm( zDCGT7w|L~LumaRAwyqzfnwsk0ie)n_x)ayk^|A%wLEH{27PQswyW7+A(3QZ(2IRU& zSTrP!?y7C(y3b)Z6`c54a^CL_WK(15-U1lE)P)Q}F@5+D3S1S*y8oRKKnKb1+w*Tk z8plm0)%#hq89n=9%fHE3KQ>jI3JPanPb_y?uwhf#?pGzwVdH(0h?3EyobLJcBhba} zY`uHE$zGQ&RiY!_+57bbR+BGbB~Ue~k$QasYhVPRN#?ADZz0 z;{HPP%stYjl0Pnf_v`r`G$_8WsQ6|>X0l;&K3@{iC!Jpa_rgP0d|w4x5xvKCSAMbv z1Dt-Am65@yL4JK(&gqgU2%FlbE%EDgl{X>&0)uLpk?YaO$+Z z#Mj@|eRVWSTMD^U=Io=BlTLsa+{#cbpb_QcTT)}WKHm@Ab<&-lNeSHLhk^P6v+^EuF0 z51drmlWkfEpp7;7$F<1OR6)WnQ(QYMpZ|#8#t*G9X0p)Jbw4TUR;(}hx>Sd-LPSNE zT;>@G02~=SPLD4W-@*zeRQ1~rS}U{HsvP;lwN6{)Q>|$IB`Gl~{#OcaV(A0!ntdI39l98$ZA353U}$)yta{&xrrj)VRf~<+^*loisU9Boj-q@$u<^ zlMT@R{W!*oA(fXO<(VX5n=GXVky4*TRzm>2>z&$*UTJLphQ!_8dAlZB=92f~$~hK| zdkiJvnZ>>Sqi7^@fB8NQ3F}$(Oeao zQ#j`t$-;Z`hBwTgL!P}J?pSm`CJ6RCepxc7tXPbbVc~!CO3Y+)=Xhf$HgZPHVy zkwJ{8D!tn2S2Yn#b*xa5M1=`r_%?dyBj#Z+CAU$(|0_1A<-{sX40@fZ^oR`1)tx?+ ze~1KAe&UCAA4+0C2nYzSq}I1j@5e;c^U(od$pg3RGLyD4w38UR zx3tJeCFP06(+92w-zRsA&UUa6DaLtjl%J&W?SB=P`0HsF3s%fTHd6FFT1^tBJZEt) zO1M6w{uMgg>bPAs=l7yEqK^*aV?xtY$|QN(=1+|2F~Vs;`ZSuxS&W`tjPeTg7*wtF z0r(#x6($n-=QR;YL_AL18bu-SH^4adr~M)x7DRA$@i2nj)EA9I_6wl_t&wSIG>FuN z{EB^jd2g|SB_F1qo!tsc*^I2(cK)b7%HM(;j!#F+XCV)yTJbBUV#P+C<3=+|5-^I# z?VH#9$|QKt<|n_a@=L&Ji}#Ifp+iPyraqkGDwwicc~o_GQQ#G8nZe85S;SjMjZxv< zKJ%KLjrD(-8lLLe(am1sru-fnTTs+HI~HJt#Ry8u57iic z?(Cd%p99HJ|3IEL@CeGpkC2QVDmo9faZ+fCgta!yktg)5bu*@x&g{2#zNd_f{+4by zXqkdc3do0|YCg0?VZa3_TLhiRxSmZp=F&}Zw~;vBC^AD!nX`~dk)KSi2-klQj#%es ziu|B>xE9Be%>vZRAmwP2+bIRYSSsjGHeTm`v_EJmTb~;@xwY}P_#5u_IbKfxh~M#< zj5p4tAl&GmFyH7-tnF~yCzLoaY*&xy1M(WQv9Tb)5Q!CljDIEAmRPq<{`Kj<_Z%MY zWA%&gNiYaWbK^U0b8YD#{cHIG`i);GTcq>l-RiIOPtWEi7g|Qe$KWJYLp@4bB5LzGJHHs;e+Ys7y4^h_ zAyKLtRw&?CX|tIu__7z0!%|jTVzVQX`%usy!z}x}L(89i3r<6UP%r_nzWNSLKA5=X z&zi9eXRb21pkR{SgawjP$72zurq_UH2seD`<~?6IX}5%rS4a(&lwoQNPOk%0_Gj2& zi=#NdH-Kx;`-K=ixK&8x#sB}iFPq4(udY9K{C@eK108vukT889E@0j(u_AZ}N!O|# z1KO>gop(n=4Tu0jva={Y9x+QmS1 z%0ORVC;JkFJtyHheo?>6;t~^j7Y`H$#e;=J$ODCsyrDeKPX8Hb{5z;!zTkud!$e-i zwx|#8dLr8{I_+71dz8M554&=1Bk3xNA2Yc51HeYQSXBGXkzi}BxZAW`{D?(9xNZ6J ze*)hW{|md_|1S7w>I)7CtXqHV<0S=NtBZzrdf9KjG3Pw(5^_8%NI)r!|NDB#YEvJT z8FrLIry7%*oBITaFQ<#AY@H8rUir7YJezE9k5}-P>?++uP-8*tkaTB@;(?7Zbv)hM zFl4<2De|xs6>?}l{fLB}`OJ6)a5Yu7Y+A$N(!?*o z3pPyYH|EJfM|pDhXR*So1?VMJR&8ix?Ei69S%wbGqEvf&B+%9-S$iidoVGF`nO?#_ zr5+}Dk7+MSMFx_H2T-Acf8k$e3olB^Zg8=tOqbea?4_F>8h!nlz_)e}7I zJ=pa0^q=Pa>VKX&E7BhiNf@_aPV%uZ7p%x+(L8Gsv;ISZ-*~rPJkL- zC!vl9npo$(OM+EgTI>oHLO)7Hq`e(=f{ib(o6)w43t7TORaNS(hAYL=+wwsJgXP#M{hM8L?MC`H~!W z>9+ulNgSDKAc4`4m5wd($b@;}QEAoB0bn1iGg&$nb(nmO&xHi`i^8jTU5fPaF7t7~ zs7N^pa;94vURw16E2w}KTOzESM2rw_RZFyg{C;3){z}sWm5{{xUW6_4NB&U>-80fm z_rVxNmad3WfRiqDSFjbs9}ui4fYjM`fc!)qqUR_)Nb}*ae3g(pQrx= z3+MXi#=A%}rsa6rKN{FSI%1_-y8d8yKhZ2q__X^63f;H^8QmjN~&c zOE)zpJ!v}e9s>^age=GqH>^Ua=q8qc6EKwMGcbMfUbaGDVG@JDZjsY7-pxJJ)`F2B_&EFc{#>^SjX} zKwR8ZoZn}sROKK+K!srF-9wV=p*>1AZaKhONt`#Ah6)Ap`6J*XRf*T! zeL;yv^QK@D4M8ZCyOJu1aTGV1FD+|CVgRf^|2ZY2Ak7rd&P4|wEltl91~&c1ILA+^ z=r)tt`@(Jo_=o4pp<{`F8?4yqn}->b)Tx2_>Q}=Z97GfpggxW(CeM)y>UZ{41lsiJ zS6bfg9Cl1ca8lNqC-gnY9?1V}(; z&FAhN85=7_x0@P*nu?Ock4%!&`N&hW>Lx2S)9;va{v$r8JQhvy5_qfGr)23K4$}OtUK29TT))0ZJEl1O)F28$&a0Pc6 z2PN~y(W#M_n@y$ZPbp%$*_Pb;8>j>=;K+@q)Dv3N@Fm1&!)^O*~M_Xy-PgDF4)QmBH0RE2fSuw9eFMn&UxcaFO)b7Hc%@P47| z6+hF`Rn4p&K8={n#3g%wZ#X{hLE>A&-N@e;D(Gg(et*7peLhw19@K(Qgc?hc(eT;K z90(Ykem(3Kt%x(oEEIvpLb6P$Rfc2$L4bsAE@@Tv(mTCY=fqLqCnyTE1kAq5V1o_;qF*VCSL)_^cd%G)oCzIuGmnuF zX-X{-j=RvB8H%fviT|DDO7f zgG|8|>DE-;%s_<62CaAjkx(=I8ff|9U#mk5A89;RZ5t`%Du(#|=2JcKMg$e7)^HVH zv-4{esVKvp?gFm%2qcE9hym7$!1#bEYzNexM_9HQ0RzVC#f0D6G(?YH@136F$51s6 zqkX$sa&2iCy>OF?6iz<>uFLnyb|*&mI_!%mFf!94gUtSlXQ_(73asBlFtMg~Q^}HH|ECgVlU$VI3n_(^)bQRHI_N(++@db#^1pyl# zb;Wo=7cVqAxJ~5b9Y`9?SS~ZTMV(tnY`}&J8P0!noDBV7&b4Ai<`46`q5?k}uNK#N z4%#^%P(Ea21HJR}iQ_};0D9NswXpvHQRva1AY|QhP&ELiEQpd(hK*9H`0gwb*HEuW zEnG0oGhpPT5IRyB0b-ZTEAWfzj0|#b2R-hQG|o{F>EABzWS)l&=xS#@kN0}k`hvhV zAidf7wDEi5z1w*KUDIt$Y08IZ)Dnw4-Tb>Pw6|N=$PJIdO;ZZ1=M`@NUk=1eF!(`5 zC9w|wTfFLK^m1`g(O%ub?PHO84l3?sxfo&9c}%HE}h8MAm#gF8qzJQr`<~$B$LIHG7zP9q;Ty z8p!*<&0jaklxoWWU&NhNmH&{xEAJTEc6M5-;t2xH>a_><5o5KmxCd==MhZ~)mYHu| zS%-CkYUC;|K+Pu|t;BSlQ#OFIX0J{Wq_pXBe^cze2Sp@_oKmEf5W{6Q0cSJ-SvLmc z3umEJS^7gRP4|e%>`QrpHoimT;9sBKyx$*jMg~`>)c^SDvH8Uc;Xko}2AM&N&W6U) zz0J#Wnu{J9l79o0c+0N9hUk&@vcXy%jEKM({on$0;&K7LXjOMfD^0)cdy`y-=u`Vw zGdgPbv~8k>{`Xkl{yl)epqT9c zE^B3c&FSQ(cyY2j5E#-1_jv&$7o77I&oxUcD=e`WrG%t8lzdt4U<006hpk~iYM1VC zX(+FVrkIoW#=kxAzvsO_f7qKiuIc80nMOJcznRL)p8o3H+kzU-kYQ(rz|hkZphfx$ z+}I+6CcA+?xLIB%oIMZ;I~=q-i=+-zevNan1fR$o-7^~;;a8!*NaMLo36-vR0qKOv zdI0D{D~}pE1hV2@<2`ub3((u@NsIqwJD~sj#gqElZ+F+?T5J=5hc?jt+LNrK0H`Y7 z=>gK_X3LrvqSZruckd%$2DK77nq6(_0sqYe59SyMqGFfXsd0A=W$+z)3z)S1B6&cs zs}$gGe(C)mjU^FumU21dWEqmO14$U*v zG~&N%XbnM1CG*sxA4bfZmz<^#Q!QO!6cb&NlyB5Vgc(ZNlL_@1xncpue+DsOzAB+o z;;eX*Ui|E_veFuXWFeQFfQXbCNY%R&0#gBh@ zWyIN6(=X@B;>fyUt{nMj(EY}r5+8SC7pe}<7Wb;}JJu*s#OV0`swyN<%GBrr=snJK z*IDY|P@_bBt^)V9h1KNb2W5p5amGT^K~|BJo{?@5ugP`%3GcCW0+>mcYP=>E`AHMkmvc73+XjN@mm;H4se>k2Webp7e|GrNBF zdcShuBR?XD_ItXiR6>{u74PWGPwp};$Iz$uARVVVWJXjuzRMS;+OgjGVJmHv#zHDv zUshF)+#Ypyr5}S8%xpEQP`v!HT;-mcUYw4$?*s4sknxWXZ1(gy07&`YooMy%<>>nF zQxQGT&;qk5F`Ov;_$f)DK9wQ1&ve)Q-GHp(`Myef6SxZzN%_ECfUHYxm=~Q>a85kt zQ8(j_`i3>q{>KisDznA%)3fN(<88slSZOyWlaOJ9E@qDOgqVvLc$e~)jGX=9uU&Tj zeiilMpMvv>(%lo01zYvC$Ehv1nbLXwiNi{Fe-0y~ zUN1&V(*{sDRGBVKkpDOHEc_P}m!ahrIA>Jscxz`F{X*}D{zWY=>dyTE@-GWXH@{g* z<#g`J!(`f}@CJn6jncibdG{iXP+)1C7-MnlPo9O50hdCe(WD%H_ZDn=}~W zcjmcVi6p+lsjsjjBvcWLMRS;zPC-uF#GchT+!JQT?s5zFnsC5{Bp5R>F-86$o#jC! zCacDEa=3W;e~zLymRz^re}&YrPH3wh_YG{+wBjWGAM>hoF>jv9b%S|Ri9MP=Ul_Gd zynXiQq=hf><)~DdxrF(9%XHyE$o!0+-x~9Ep5?UaOI3=Y+2B_!LMjnvbP=R~^Vjt} zob{zS@gJ0PNE)VrHneLz@rMNgh_qeKbVhBW*={g~f?wQA%f!B(YOIoaC>b|VDlB{b zIwp#!g}UC|hq!_;YBSDTN6K}H`|J>4oFJp12;Q?E@tH#&5uYX(G-@qh|K1vA9Kf62 zN=7C%!a|-un{aIXoqd9V@ZO3QZoRQeUY>L194gk*<(flqm#8UcVN!i>8?gjcDgWA) z_-rfu_;#TG2c_M8`w1CjX+k zwk5Fui2$SvZ~h_}!CbW@t^onOL2Qc{oO1+KB4CW=)iA5CgwZPZn;yt1*B*RLC9wxI$TRU zGJJPJlh|05C?ejP^L;*e_-!2)I~OSIQCAbZcpFzT2sj`WVlaVKlza$*G%JT9Uc(|`RLF)R6ljKPWcV=t;JhM;0)VA%HtLzQm4J|GfM&Y*dN; zct##QX705QU4wRbIU%GpyRgr(H;Yqsxib%@Q*sPdX!Gl88V5}PM=VPfUryhNhfo;_ zsqzhXlmA*XZlA>R8W0ESUFoh2?PM|35P5C#xK%m>?6mDE-~+Jnt1EW6d7wFw!EOeB z=t`37`^peLoI3lgWb=vSaWSXviw>T4xtpp2Nzf=R87i2g&VG?^11f1)DXH|F({k*M z|5B1Rdh`lmSh+tPZ-@)%cy;*QUhZ?-VooI)FP*YbG*Lu^)OyL8nC4<)FNTk0)V!O8oO84Lpp*S9;P3SON6|(3iFOlFr4n{R547NA-PIvqjA1&DlK?chQa~pq` zS8Kw<7GWz;?B^!FN3{#*Qf@$k>jNoZ2r6jK7m_G10@ojCwN&j%uLdS};~fjW zcW$-k!_-A3G@(@dEOm1eOlZnD4dGn8|==11(0VC`t1 zEvG?%`n36$Uy+$&#py;5(~{im-!WQVTPxxD&GL(QOjAt2l03dD7Q_u`&@A;@%daC3 z0_PfSwF;52$!xW2w~da-Vuj@4nb?74dj1piFcgRi>8CF$Wa*vAa!Xfy^giLD@4vJg zPC%yabe>F%n9ceU5^PzS5B9NAUmsEUUVo})hm4l}BQk_rRsQ#{Ch4yd?g!fR zVneFEteQ+RvLoj@Qf%D15%E%0ny{)w+HGR^UVS^1K@l{n2?b|O7J&9~_vS54_MN}{ zq~yf-9xR=2{HHJ)N%#018{tb0E%chSi!T`#>&l}iABRc?q+T+(i;;*q_uA4Vc?2u4 zx|+{!bv~-UZ`>pmXZCJskkW(bjPN-oD6HE7dmByfye0$9@Nz@9C`ktguD|SCyi=!W zG>i|tV7SGMcVGI|J}h9tK+u%K3P~a@QAYr2+Yn>Y4t+W0uqGSdWD4+e`)Cr zHPX;v0t9fgY1_9?l?B^|iR^_nZbkB`lNZTmdh!a*&SIW+!iu11u2Lip^WO%-fJ)c> z5KAeI2(!0`U+RUVTN|TX982u;2Dn`67Z+%f*en4)4WzNvBvU6!rLXn(~hZ z7I=C1$1+TUVg3>)Qf{Gw0U<*n)JKVc-fAYfdhv0v%@s*K^3{a1((>wj*}``(e!I{C z`pLA%L4C&`eSI=QeoWe}zmk9hT7w$|m&faP^yDnm)giFrL;`{u2#*rcC zGrHf{pa5}9L1djGu*tg4NbmfuDu2xLr)BQjh^{% z@qJbzLm}wciUF!*!m(6q5j(MCUvDJwJBW9*9k zqdj9vcZ2}2UHcW4Q>TjsWr{K0{u&r6>&zK&g2wwJmSTQo6RS-)lr@eV1MY1?8diOTDJ2we9mgka_Q^7S}swSoEX3lR2Wc%tuxF=b92#C$GjHpm|>E<6vW9{j6g zXlD=Wa0fQ5p}VK$BxxCDB2X#+L@9?=D4y!*=XWv0ZGAXFqP-2 z(cQ+$&IeB}zuRK(!>a7JoB9jxhh-0+joA)Qp4RZz{+4d8a=+JG9_MCN(g0TKKWk0G z^$K6YC*}Wiao!k@pVBdvDv>hQ<-k1T-oBz<5Jd!0g-V3w^E_SL?tn-grEVHjj1pn* zk|(dRXY^YAxgqcZ^87W^3Mfg~Bo!-rP7;H?Fxf>GR@*X{}OX>*uX-wc6Fk$EBLhmK(pPmGhL6;LI!NGE(msE4_-{|}1Hf6S0 zug}cUJN^3kuPwW;XGbUUsbnxH{(jZ>ILET$&&DwtnAj_Lbcp9bCN-|Mxn~y=N=sED z`r%HSSG_YN$Wq_~q(}P*0 z?xXuz&rj?(tFJG6X^yfUH(-h%;cc}X-8H)2ZfA}{>Scx7MkkulAf6UJoj{f)t>`ZnQRb3|%v@|t8+&(c27abjnn2xNMdSt6hMl7j7n$yW&-DUBuy;irLRLho3YYZ)ws zo4z)VwNDaWg?n5)`8)3GJ(m6_BNnBfM0fB4cNz{7WDt~|XIjFjV4UbHV6cL2fm(#cvT^(Bm)WFa|d*i{Ky@SixnActKHyER(o1Bj6TnNI0 znNO9RQDH%~J$ZzMK(~;qBSmp7$wngafqvR`T^N)h}DBAq56%L*fptj6GhK%W*%zHnaxt}C#{JNV) zbLZj#7OV(kY-T(zRG@Q>9Q`#V=6UPDo8QJ99~)@tfdyaB+tCcPX_q~JJhs}MCv#S&~t*ECqVRlT8jRqfbo@#gQ zezG&l3cV$v)kK2G&#KVwNd@W%NgMj5CL}oRj?(~&h8I8PQ~gM&p`Y%LvcwTdrV;-x z%Y3NuNk__bTv<`ANEA^dTTBeEhT+EtSW&>+9T!h|+7;iP#n#yL*EGx3ZklX2T8ML_ zf``{=0`36&340GC>Bqb~Lu{YgtJ}B)LT5wv{$PureUU!`78KFVbpcmz&NvOWl>ftG zou-iW`|hKvuT6%buvJQCO=^p9{7zt|cH#t6Q&sg4hqBpBLX%=Bp3W&;k4pdGSS{*E zSrqmD|R10^*8pCpgiTOHFzJZ@-hr#N8!$7gtq&O6y`S)^Z>2t)3 z!dxLDfrZwy<6DQMzN`-SbW{Z8^~On&l-|*WNxK{qqTTrvgbHT%2V63YGgyD822vsrBU`>N&5`YL1g>E=IM*XDADx4x!*fgg%)LEC0#Ufd*p`Rtsy z9Y5pI!LVHwgo1^HtrGf;R4f@bUc<3KYYI99z>N;>FwYDe?1wbhFM8sT@bh(3jxz*m6)U63C=z^oQv|Zy85;z{p8%M(*S56wqt4$+q79^$QQ5OlG0_ce`7c>H2(D^vZ+rMA=dpO%}lH{BHQc{Kj2VfzH1fuw`ji^Mn z(5}XYt-y^$^$OKeF>@vHPg@fuus5!m){J57^q*}m?S1N)`P-1->L@gm!=i4Xh6YXI z66n#kzkno*#vCV?;X zs^whfXhMSBnmj!EnImv`nD3v+=t-S)wE%Dzv`UAt-qyUR43>rgdCg^97^uSvu)PZi zDnG|~fkotp^Z0{bs1-7jLI$tKPJzZQ<0;1@^UNruV#sg?B2k1C*Ky{+O^?b>4l+V>8)P}D6E6EhD|(tlOj@rR zvN2xfW05gi%z^&d*vZVJaC}9Vt-XfRg|I4w^dR`co4iyTGxS19WAew-efr|< zu{FyWFzvrcpqEYq>$_|q>wFuD?RWsZvd6!zeG}BD2%EE|(Kqt#`Ks#$GZ_ii|CEYpTw(wZTaDH45X(3FUrD4u zx>dq!)}8BjXrI0I&qDi@=*|Qbl$1U++Drl7M^^qt%E~N3>Q<+_=`p&lu3Myr(r3QB zW!g7?iJrZ-#w8kgX`e1Cqle%}EpF+;XoI@#in(3=^SH%(E{MCM?cPG6klN|?Eu)iYU z{pp8r8Z@c{w0e{c`0*~Em=r}?O_)xz;&_cNrV6{m?}LAbtAVN~w6>Lir_?7*mLfY^qICifnGZ8T7x5)s2bvYot38z7lms%--kz?hsi~1! zf=SgM{W4eIWy6tFHJrFeyyT@x<>lA~n4f-EphC!J&0l~EFwt%n6-1qC*A+vMsy8I4 zW%QnZ^|;|=%ouI#q=NM?x`WZL3{4OW!Dwtc6mE=0=SuDO4HiFCfyaXn*z5e^4T-n0V`K6DCS*aK8-Y&8F;_^~@K1zZOp@n&~D>vvbV`fWb>MqYg+MFpsN) zRPN0$ht2nNO(aLWJWnEZ%`zVi-Ec0sB-cUWC?j3N!oFj9Ey=>y2t+i{l!+O1f2&gS z888p>!n9%!1~#`q%4HFYcXHtG6;)U8;2!Kp>VZp{Lt}#?>yos!8ZZ#@Q_u5Xb{U>1 z37FJWAZU84#vMH0!1F#cXQow+_mUx|!duB{>F&O{r?umnY2*g&N&~J% z_enlz)3VD@w+BuEhcdZ#DvTA%Mxjo>y}SEi$efMD8qFdjoVZv&VT zVI$yWE44dKF{q`==WygS_kkXsml~&N{%vPFFdSD%X-FS=bYOpJy?_C8>RgHNe%Cu* z1iMZsK7^#DKyq(Mg&zDdXy#4uU@)0+9|^!LN9Uc|ZO!-e=>8itZJneeFmA zhxat+xdxWdR88G95Ec%qw)X&Ip60!{SB$W`%x+H+i&0LC+;>#A3NbNH8*B|JNH0tW z+aUPCcVAc{m0lf(v7w&JOiK%Z1%CHj{~&bd9vJN-Az z9?K1RJWCL}f(=`g^JoFcDiZa4EgHqnt6M^p;Oe7iZXbslxRriT-TZfPsn-Uk7;&7a zO&3zR@<&0qaWcf`&75HS;m61^@4k|h^UG;l$n?dP8KK@kI%mzFs;$v;15R{nT0n>Z zEOU$LC?ZX}^idkM?Ci<64e`=U6&l?p-d@z$H@ff`nW9dt$%2&b$VFXB$|qj0F=40H z^Ho@!lV9xW6X-6SeI-%nQL!W_{v#n84j3Z1p{2hs-=FODG=%%Cf1F^xh9JD_D|-yD zPs;$e>%cuIR6aJ-K@ty{T@QBjrXgnzBjx$#bPa!13YV9cS0mu=8p<0o z0sOO?xZ>tG0n!@6EQ_9!3_ak#WmS&EWE(rW>^UF*ufy!`TgINlnw3RraZZU;VY~OT zcVgXBk*f+6okK<&!pwn9R~C6KwP6pw8{dVk$Eojm6KOq!&Lu@kr^DDja5S>_*4xd$ zgl}zXSv&rc*3%taXI0W`MxK9?3s6TSQ3Bz8_!t;xJSW!imXLcz1HM4@H{Al_*7Ap~4bL0XvN=sLrkI!ElTJ>gqiWyfu2?jg) zZ{-7Ts2*O;f40Ic@$A~=@AehD$wi$0vk*4?=I`tK{qkd$Y*deh*@nrdr1oE8!TODg zL$&x>H8YDpds(Xqvv5|wz((ya3tH&PI(t|;FRL(_0oU00`S;Lp*SZk5(Cf_*3*6f1 z7vUgT!-D;Ae=%zH_~3iRSe1J~o_@Oge7x$2Pcr-cL#nAh+%0?)E0V)!BuHpV=Vm%r zaqPGb6JTIa(>tH5jhE&7XQiZAs3uuT88~%FjZ*bVOM;YLqMu4JjY7l1q+XiS3+rMu zB#ia^oLQPkFmA9%1D{dg!zp!>@!yROkdc6Uc?GzbASq|08{TZeEw z8YhCJ@{&#N4Uu&3>w|wxI>1yGoHW~OcQ;v}J4fhf!u%@KdFtu6Qb%K-^%)4e`J$e; z{1b{lx3F|VS1vrdN?qeU5yS7*^};|0YNIdZ;!|hja>ljN-y3D1QwNEuseoa91dWg+ z&>s(eX0%zFZtQZe>r6qjVJP(>8PYrs6{_ePF8^1UZtG!&`dT&j5(J_ie@ZpL z>jgymcj+CfU1+4oY;>X9KM3l+wT$9_1Up!P{mg)0WcmL66l0nW#e76Z*)fRC)dOdG zzw$@>s}a?_wAJ_WASJ6uz(x#2($r;*)T1fUc6WFGYN0Zy1-KluFr(Kc7UCu4jUpuC zBcO~gTE)0t4)v*8zV-@lpiSi*L}7o$#q;k*#SRPAD$dLvm1;xHw)DE9QcdzbJW?#LIi^Ih_-~TGg zI~}QHtm3=-b;5xPaxaJ1d=MmX#HJu6eqjvu{8{1!03jQ%Le* z@XqJE&LEmlT}#MJ%ZY9ptmGGO3iYk(!M!=a->M00+S()mlv8T=KVg!{I69=Bg7uNG z1e9Jko#ergd2%gpb>5WwKw8-k=n;*`z2u_4JIp0_NEboSR#SU+I(XJxTBHn_FcICU z6moTD?TCi6WWjtZ8s-&$Wp#`J2Ur_Lt7mBW_x402j!`bvJKqkOivUSUNjxD^&txEZ z6uuG7c1X0hV(mF;5=5wpXemWmN^;WBPkmF_#!DjRk-cyj?Sq$bFxqJF zn5VS5<;TdEs<=Q>h5aj2Q!35h)jL-M(+mVZcXT)ZOK5psq!agbJHAn4w&{mudj`~% z1+hto%{~8cFWpo0?)`6%{nIb6{{0bMgiDiiNQsSK6wld7FaFzV;|?)dHTgd9O;qS* zil`60h$E-*cM-r=n%pCQEM}orF8^_Z1H7y#U6iq{J5E&MqNUlwA1S|H?fmY&%61xt z$)Uzj0sUmY;TqF*XL?I=MX*Aw?*I(>j=koq`UK-&A{!mCs2}!HC$UzOSchxF+nI(0 ziLYnKixGNRMw>3mlrAOJU3~xDGEf?luINU*kJ}m zU=T(#j2E+&&K)7=;GibC)d>i2J zNdHb2t!Dk3lr^Ar-xygVQmq|MW-+HNlKtT=zWIfsncT$-^8x0SGDTJ$$Tmu%6fLeP z1k*=h`Eq)G**3AZD{(DfCr9`4130wnZw3wSFu_inr4d~r$p^AGI~Ti&d-z3tgtWA( zx6aW5w$qFo%2pkP1g~T*w$73MIMFXGbyTVMY0@3xIZbIR6SjwJ{w>hVA1{%JsaCR) zbC>sZx(KFxbDB!gm{^C-gb^v@BUJ+vZ$ z(jPkZPrk=`NI8+FxUO4-sUQw8*YJM^9q#K%Xftz-sX9bz1~PgtAd9z&JL9=PK+wMw zBVY-NiG%Y(evy{UK^eo{cQcZOfnk<;&%AmSh`65==;NY2&gf?=ncxUcT<-DxNS817 zB>8x|9pC!uuq|b0`Rn3izAD{--*mQT_gkHK4!xwcH<;x;c#4kM0(zKkf~CFYhD_Co z6IR4OsMVXaD>MbB7N?UbK)9O>q&cU9@pKbu!FRxv$ocPOx_UPQRyIiEw}y%4v_P=_ z9wFsE{=q`;P)#XC$RsY#*bBDYwPREH`e zjlNxfGvrWr$o$377q#3uXiHEP(Eb-*756Ky9B={5 zWjDc`mI)5`u&T6&%#f>(h;K|wOH0Qxcv0?7fi14xY`F%Yn{9X7=d=2e0Z2y<5y%3# zbzXmg$RjqxR-RE-K0JsZhway@wHs%qDDl;@%grF%=44W<{D< zrW1ddua#Upr5X1Q?rmTe{BN&7KxziYi+9fl8)@*=RO!k$aRqK44$pHjSeuLMRyaHKW3KC-i`qc6A z7)twCN>Ar6pZ|L0LSy&! zP?CN|?e91@=lrC2eK)VLV|x()oo-xK?xBH|mk5xs^Ur}YRGBP-av$#_ zq6fbFfd6;ELfRD&=GHZ8?JB>hj;+{N1${Jobg0qc5P{8-!Qgp@b=YlZx-+R0O9IH% z)LbIp>U{97d9;b)$*Myux|ko1!lK1yhE*t$K5DQ1sMaR39CZqQGQqZO4|=H7PLR37 zihpcb^^R6WA;a)7SlmOF{A}Nwx3k&1&=v6f3URUNOC_M^^zB*AT_}}#R5U9Xcxk<3 z_-P|bJKthBW~!ff0}*qf6VPf6a^j=QjYh?Lq$=4h-%Tu1UpzPW@+nD_Vp}BZul%Hn zW&?6e2XIrE=KP4bpIWRR^{&1nroF@k; z$S5cR&nnheS#XlH3b^K(sF##DjbibvmhdAM0L0(h^~ zp6_7<26da0FCWn#0S+LS+YWC5?JKnEz;~yV$pgG4pP9rZ3BzWuP8&&+1+Mp%mwQ>$ zwqm5(8a?f=IJCYhlbTx^U;p*`v=W{+rKl%urFV1gC-6X#zXz=Ty~!cf+NFuv%$?C$D% zHR}^vS;@Fd*OX5WfSgzo70XFq6-@8lcrqiIT=cQBvE`OVkJhpEo!*fNU7C8k!0gZ; ze+i!XRFi=4Dx)1{$x!#>dAi?tKJym6lb=Tz|Clv>CsFA@R-2v@7 zUBDy37B;@+9w0M@ADStpM8l5J@nME-Nl8i5^_EKC#L`~Yt9Kx$cdAm>aIv^-p}SZr zi7R$!<`-5PzBLDw8P%l%Mo-tMbc@jB`@)5=Oe3E~ml`Kh;FKPQ@kN!{+t`$UbQua+ z*XmXcu?|=hbi|C6Qc%_Gh1^Fe99;gVyx7Y+)Hp_r;%Nj+Qk~DY9CN;iLrv5&y?OS65fz-Y7ebMjPKex+`}e-DX{8Yjn(W zI0pmh^%IXFR8O?Gvaewtmi|fwEwNg>G`z0Sng87=n$Cl86ygZYB9AltdxMr}es2C0 zdFyCy5o?$@^Azynpv=4WH`hehR~AQOLLUTEv#LFmnlr5Cl~Hfj$WfpSfV0 z7$QOFXq`BVB|rlpi4{DDesk0?QO^~>jP?#rOsb^UB9RCGZx~{4gBJG;2oxOw*#;2h zkf87dtmqcEo*`L-NBXia;I%HC+^DgaXd$tq}!j@$~gIsFmgN6N*f+(V&zr8imfSKDi#* zP#oXZE$$(>OR%6JxI=;k0>J|_Xpj&H?(Xgo++iRD8Qd9saCZ&v9-N?goqK=pzE}0# z`sS})Gu>V1obEHdW$m?!#%UAtq5Y4s?^rma!$ajX8d(=UJw05V^pJ4qiiIy6)uWlM z)UAoU<^NWWsuU1DC=-MDrBf*O*RAV2No;3U)Ok29Vi|6xh%Kv5af8uSG}tm?zvRAN z+Lgw_66Nvy=Py=f<$_Nw>RblCirj`@2@tieG3r=|3gR>h;rz(@heCIas2NV!(OS*cjp!CH-F!=0xPuB zf&y~YZ^A~R;y*}^x<*5dqc!cxjbq>h(F{XrAXgDH=y&><~YnQ0p8A*4E>Y?d4{iEuk6I_LEv!ZsJO)Kup{pHV1 z3_8~rlK@Mer3Hrujfo3DA9V&$3{whbZ?YhfU@+c{b?yu2mOzUoM8|ZyJ8Ay4<%2ay zR-`|$&6CT=4~!ND6N_LcdU0&s_bNM+)+P_A$U>fT;<}Rtt#*S80cv!|<`puDEaHr` zG(`zVUFs?ZU9J`r2>;7lB|JQ)l;zwNhw_$Kl|%LRP&Kj;7I5E|NQN;i-q8cG#=!HK zpU=y`Y?#iXA<$o#^{gU1Rvn;7q;Jbs_GEwybSxo&FB%wyQA_`DMos!_CH2V#eJ_E@ zt5q-FcAYiZ|0IrqD11oAg`MkW2dxG!A)(l}6PB-G zU%S!5E)0XGgeRy`I|DRC(UgL?6nq$gEo@q);97IFMvMqz_K;Y2j2*Y#ELY$=qpwQh zAXY(y+4yenQHEs`f^3}@;w*_I7ic|x72yp{)7`E&KNFPSvrSV&){?dcglF)0Eqt`Aw8{~0fctz;B;nm7pCOg>m8QfsHHx3~w5caFWL#%N40XelN zF$d^kUNNR`46xl~0gAe7jUY9u!BZ>KlNA*04vH*p;=Y&8GHyETs?@B_K`wM(FhBGE z>OR>Y{y{g2Zj}ls{&9PFq4|v4;b{*0z_C+3M<>evJ8spX>q!mb}f+%AbYuN-Fgb0J~t`OEu)h?<*PiQZ&ofe~ZS7({EN);vQIf z%Dn>u$TvmfB#bZz-!$UcIAkmEkot4$7N1p{ti}t$G)INW>g17l4?P;3W;m5=3#OW$dV(KeiFp4fz;d|0CD`lHqwuSb*ffhd6}8(g%a zo1zdAbW&T($LH}@2PpI-SV30&EU4g6E+b@0N`UU1oSZ!Tql#C-`HiGNk_lQ+DnDh) zx=nOa0d%U%v<&1X7E3Lfd@^doDdUiv&v-&6Vw`Mv=%0nV&4N=S9YP|o0(eahfR;0} zN_LC$A<5f=r6xza-w-Y_%UKRE8a@&rq(+>X4DTZ&VOQPVe{fjeH13W63F;4eIhybgZ- z780{J$ne>Dx=^&#^nI}f9{T-#ZJTF|KQ;`soBEkFv0{lUzcT>=dz;p(s)|;!>&&^> z8#!}4iR|?q|Hwhidr1-+fxVK(^`TI5%l*j$tOcFnnI}Esg+>>S2mH3TJXcs!o8e;h zG|WfbnG)V2Jp8J~1iw^yX>jSE$PxtG8`6Zc@7>JgWE;u3&gxxdIw^|w=&28tzv&Wt{%g2nDWF2q~ zl$;vs;yi2OIwz)5+m$V>-)36vRH)K-#Ttc62X%p-A}&XJzt4Nne18v%%yes-a)^bJ;~Zq=;sNX804)i6eRCiRr7mQwvTD zH@v-eIIn;|2dUO)$N`xzW8zDvf_2;FynQz=Mm(QtUcijz^R4acr07>LR>M|f-?+Sc z2$Q8Ux7i~YU8)@sGT|$R5I#slf6=Jof7+te=uML=rMeDq;U7#5L|^s|>(Z&A z&Tpet*{j3KftAN^KusF?#pvjK*xBX&M*pyuwa#MRfnQ~zWV5S~`3Gid@NYmuNbQ2) zI#wrT-gjXqJJMuv6x>PjL~8l*W2VQFe+Jf1gy05J@3)bS3b{}}rO@fAq(6cKcZE!x zc73x6eF!A!FJc}$AKV+Ua}E$WN|6KIDjM|gheDVns8tFRa|*d)#>}b?Lm$M1dmdQO7G#Ih7&xiQC7f2i~AwdX8hVsc()*-doEA%>-8`Z`D=m)(=b*}b=VOeMu za|MYmS)oa@4>S!*X5#JymY!ab_A5zgQ%@qgJDO&aPPSEzmEZz>jnEl~y|evbPLNRI zTw4?4YiV@#GgHB@;FFucJhE2rPG=}Y1QFZvu-PjtPzg))bXwR;=x06S+F3}DdLk{+ zo#^nS0VK{5dvQrwOn)Hh5D(So{@NM_NjM5h43+cS?jdG5sQCaHHA)yPNz$q{cG3hwt8Z1|m}cd8hWj93%ThPsY2nPOfUJy^b7GZX z{YBEv1)}^%5mG zmHk>Nk=lfjFv)3iY_0BIZJ32yAWyYl5cOp#4u*b)nX%IoCiHBzM@J&QhAn`8%hfNLh&t2xSe;jFaypau~9*6gg%G%0ayDZzPV6Gzmtj-lX|q z-1>ZYQlupaRe%QP&Nyjoi_AtLa|!E#9_x3(!+4oE9a6N^7?$N*6+AiI06Zc^ z*@&V=LS1P6#qs`iN>dbc{FxPL4Jctwp~Y+V2jJ9~!akKTbntu!(s3dll^x{Dgq4}) z3DWMW306cK`{%2Fp5`oiMLaH97P;YF9~SI`;hM_?dV>hNPWwmvCP{Z8K+$6aOM z;UYrWO(v_vBD&6MuF2NwHI~%gh=JG)S1X%i41m*8pCW8lTAD0oN`UsEu)rGAeYSiT zRE@#ZyHUT^-}AjZI8yU_n%r3PN@cvebS(A|V~69qXUMG0|2y zg6Tpy+0yh{5ElsrQL0oi^RsgguT~n&n!f6OoFvxuNf2P+nw`=}S#5J1(?Gz^k{nMu zKScck$t@rd?Un7(`B-g1o{-o4nTe=8LRr_Es%(DI5%%~R5Oz7yr~9Y z{V!u5z@6;eL`Alil9Ec?MJ^%g9RRo)o_W@B(V^?^WvTe>@KA$NuLHAUEeuBQRm3UU z_gEfOW!{W0XKsC*fAp*Q$WodYrkSrM;qAw?CDcN+GUnTF#XW*x<0o`DrJwHYcSl|? z7~zURpkvzX^~GjN1|&tTxIPiNSK8ghES@Kfp`KW(FU(nsJ3}_H<}UaRDkW$$bzEI7 z%^swmrrtQHmyq0a%zDi2=L}R?;u~izJ_2@dTVg`QBFrS^C*<1l`0q&h){LdbOxY0u`?Hg zJUm1;q^hOlZt1nAcCi6xZ8#bi<8qX8FLKnaX||&Fkw?ejhL$X>Gx>)X`T*_=3zJh2 zgqpQs1g}b$Po3-M4DWi8O~*N|M#LWphfcsB#xO__} z+!rbC_1x~(1(%jWC@TX3@Y#O_2OG0-k|0p6p@rp(QKDZv;t|AQ7X_hyL2?u3ye=$K zTaRQK`emP@y#*Nh!7*IzUbJMpp{LHIH^T%lF*_ZO{F!k\b1DvbL{K^hzo_S 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 + '/^an empty directory$/', + function ($world) { + $world->create_run_dir(); + } +); + +$steps->Given( + '/^an? (empty|non-existent) ([^\s]+) directory$/', + function ($world, $empty_or_nonexistent, $dir) { + $dir = $world->replace_variables($dir); + if ( ! WP_CLI\Utils\is_path_absolute($dir) ) { + $dir = $world->variables['RUN_DIR'] . "/$dir"; + } + if ( 0 !== strpos($dir, sys_get_temp_dir()) ) { + throw new RuntimeException(sprintf("Attempted to delete directory '%s' that is not in the temp directory '%s'. " . __FILE__ . ':' . __LINE__, $dir, sys_get_temp_dir())); + } + $world->remove_dir($dir); + if ( 'empty' === $empty_or_nonexistent ) { + mkdir($dir, 0777, true /*recursive*/); + } + } +); + +$steps->Given( + '/^an empty cache/', + function ($world) { + $world->variables['SUITE_CACHE_DIR'] = FeatureContext::create_cache_dir(); + } +); + +$steps->Given( + '/^an? ([^\s]+) file:$/', + function ($world, $path, PyStringNode $content) { + $content = (string) $content . "\n"; + $full_path = $world->variables['RUN_DIR'] . "/$path"; + $dir = dirname($full_path); + if ( ! file_exists($dir) ) { + mkdir($dir, 0777, true /*recursive*/); + } + file_put_contents($full_path, $content); + } +); + +$steps->Given( + '/^"([^"]+)" replaced with "([^"]+)" in the ([^\s]+) file$/', + function ($world, $search, $replace, $path) { + $full_path = $world->variables['RUN_DIR'] . "/$path"; + $contents = file_get_contents($full_path); + $contents = str_replace($search, $replace, $contents); + file_put_contents($full_path, $contents); + } +); + +$steps->Given( + '/^WP files$/', + function ($world) { + $world->download_wp(); + } +); + +$steps->Given( + '/^wp-config\.php$/', + function ($world) { + $world->create_config(); + } +); + +$steps->Given( + '/^a database$/', + function ($world) { + $world->create_db(); + } +); + +$steps->Given( + '/^a WP install$/', + function ($world) { + $world->install_wp(); + } +); + +$steps->Given( + "/^a WP install in '([^\s]+)'$/", + function ($world, $subdir) { + $world->install_wp($subdir); + } +); + +$steps->Given( + '/^a WP install with Composer$/', + function ($world) { + $world->install_wp_with_composer(); + } +); + +$steps->Given( + "/^a WP install with Composer and a custom vendor directory '([^\s]+)'$/", + function ($world, $vendor_directory) { + $world->install_wp_with_composer($vendor_directory); + } +); + +$steps->Given( + '/^a WP multisite (subdirectory|subdomain)?\s?install$/', + function ($world, $type = 'subdirectory') { + $world->install_wp(); + $subdomains = ! empty($type) && 'subdomain' === $type ? 1 : 0; + $world->proc( + 'wp core install-network', + [ + 'title' => 'WP CLI Network', + 'subdomains' => $subdomains, + ] + )->run_check(); + } +); + +$steps->Given( + '/^I create multiple sites with dummy content$/', + function ($world) { + $world->proc('wp user generate --count=10')->run_check(); + $world->proc('wp post generate --count=50 --post_type=post')->run_check(); + + $sites = [ + [ + 'slug' => 'site-2', + 'title' => 'Site 2', + ], + [ + 'slug' => 'site-3', + 'title' => 'Site 3', + ], + ]; + + foreach ( $sites as $site ) { + $world->proc(sprintf('wp site create --slug=%s --title="%s"', $site['slug'], $site['title']))->run_check(); + $world->proc(sprintf('wp user generate --format=ids --count=10 --url=example.com/%s', $site['slug']))->run_check(); + $world->proc(sprintf('wp post generate --count=50 --post_type=post --url=example.com/%s', $site['slug']))->run_check(); + } + } +); + +$steps->Given( + '/^these installed and active plugins:$/', + function ($world, $stream) { + $plugins = implode(' ', array_map('trim', explode(PHP_EOL, (string) $stream))); + $world->proc("wp plugin install $plugins --activate")->run_check(); + } +); + +$steps->Given( + '/^a custom wp-content directory$/', + function ($world) { + $wp_config_path = $world->variables['RUN_DIR'] . '/wp-config.php'; + + $wp_config_code = file_get_contents($wp_config_path); + + $world->move_files('wp-content', 'my-content'); + $world->add_line_to_wp_config( + $wp_config_code, + "define( 'WP_CONTENT_DIR', dirname(__FILE__) . '/my-content' );" + ); + + $world->move_files('my-content/plugins', 'my-plugins'); + $world->add_line_to_wp_config( + $wp_config_code, + "define( 'WP_PLUGIN_DIR', __DIR__ . '/my-plugins' );" + ); + + file_put_contents($wp_config_path, $wp_config_code); + } +); + +$steps->Given( + '/^download:$/', + function ($world, TableNode $table) { + foreach ( $table->getHash() as $row ) { + $path = $world->replace_variables($row['path']); + if ( file_exists($path) ) { + // assume it's the same file and skip re-download + continue; + } + + Process::create(\WP_CLI\Utils\esc_cmd('curl -sSL %s > %s', $row['url'], $path))->run_check(); + } + } +); + +$steps->Given( + '/^save (STDOUT|STDERR) ([\'].+[^\'])?\s?as \{(\w+)\}$/', + function ($world, $stream, $output_filter, $key) { + + $stream = strtolower($stream); + + if ( $output_filter ) { + $output_filter = '/' . trim(str_replace('%s', '(.+[^\b])', $output_filter), "' ") . '/'; + if ( false !== preg_match($output_filter, $world->result->$stream, $matches) ) { + $output = array_pop($matches); + } else { + $output = ''; + } + } else { + $output = $world->result->$stream; + } + $world->variables[ $key ] = trim($output, "\n"); + } +); + +$steps->Given( + '/^a new Phar with (?:the same version|version "([^"]+)")$/', + function ($world, $version = 'same') { + $world->build_phar($version); + } +); + +$steps->Given( + '/^a downloaded Phar with (?:the same version|version "([^"]+)")$/', + function ($world, $version = 'same') { + $world->download_phar($version); + } +); + +$steps->Given( + '/^save the (.+) file ([\'].+[^\'])?as \{(\w+)\}$/', + function ($world, $filepath, $output_filter, $key) { + $full_file = file_get_contents($world->replace_variables($filepath)); + + if ( $output_filter ) { + $output_filter = '/' . trim(str_replace('%s', '(.+[^\b])', $output_filter), "' ") . '/'; + if ( false !== preg_match($output_filter, $full_file, $matches) ) { + $output = array_pop($matches); + } else { + $output = ''; + } + } else { + $output = $full_file; + } + $world->variables[ $key ] = trim($output, "\n"); + } +); + +$steps->Given( + '/^a misconfigured WP_CONTENT_DIR constant directory$/', + function ($world) { + $wp_config_path = $world->variables['RUN_DIR'] . '/wp-config.php'; + + $wp_config_code = file_get_contents($wp_config_path); + + $world->add_line_to_wp_config( + $wp_config_code, + "define( 'WP_CONTENT_DIR', '' );" + ); + + file_put_contents($wp_config_path, $wp_config_code); + } +); + +$steps->Given( + '/^a dependency on current wp-cli$/', + function ($world) { + $world->composer_require_current_wp_cli(); + } +); + +$steps->Given( + '/^a PHP built-in web server$/', + function ($world) { + $world->start_php_server(); + } +); + +$steps->Give( + '/^I insert arbitrary UID postmeta data for user "([a-zA-Z0-9.@]+)" in site "(.*)"$/', + function ($world, $user, $site) { + $postids = $world->proc(sprintf('wp post list --field=ID --path=%s', $site))->run_check(); + $postids = explode("\n", $postids->stdout); + $userid = $world->proc(sprintf('wp user get %s --field=ID --path=%s', $user, $site))->run_check(); + foreach ( $postids as $pid ) { + $pid = trim($pid); + if ( ! empty($pid) ) { + $world->proc(sprintf('wp post meta add %s _a_userid_field %s --path=%s', $pid, trim($userid->stdout), $site))->run_check(); + } + } + } +); diff --git a/inc/site-exporter/mu-migration/features/steps/then.php b/inc/site-exporter/mu-migration/features/steps/then.php new file mode 100644 index 00000000..c4e56198 --- /dev/null +++ b/inc/site-exporter/mu-migration/features/steps/then.php @@ -0,0 +1,260 @@ +Then( + '/^the return code should be (\d+)$/', + function ($world, $return_code) { + if ( $return_code != $world->result->return_code ) { + throw new RuntimeException($world->result); + } + } +); + +$steps->Then( + '/^(STDOUT|STDERR) should (be|contain|not contain):$/', + function ($world, $stream, $action, PyStringNode $expected) { + + $stream = strtolower($stream); + + $expected = $world->replace_variables((string) $expected); + + $expected_pieces = explode('|AND|', $expected); + foreach ( $expected_pieces as $expected_piece ) { + $expected_piece = trim($expected_piece); + + if ( ! empty($expected_piece) ) { + checkString($world->result->$stream, $expected_piece, $action, $world->result); + } + } + } +); + +$steps->Then( + '/^(STDOUT|STDERR) should be a number$/', + function ($world, $stream) { + + $stream = strtolower($stream); + + assertNumeric(trim($world->result->$stream, "\n")); + } +); + +$steps->Then( + '/^(STDOUT|STDERR) should not be a number$/', + function ($world, $stream) { + + $stream = strtolower($stream); + + assertNotNumeric(trim($world->result->$stream, "\n")); + } +); + +$steps->Then( + '/^STDOUT should be a table containing rows:$/', + function ($world, TableNode $expected) { + $output = $world->result->stdout; + $actual_rows = explode("\n", rtrim($output, "\n")); + + $expected_rows = []; + foreach ( $expected->getRows() as $row ) { + $expected_rows[] = $world->replace_variables(implode("\t", $row)); + } + + compareTables($expected_rows, $actual_rows, $output); + } +); + +$steps->Then( + '/^STDOUT should end with a table containing rows:$/', + function ($world, TableNode $expected) { + $output = $world->result->stdout; + $actual_rows = explode("\n", rtrim($output, "\n")); + + $expected_rows = []; + foreach ( $expected->getRows() as $row ) { + $expected_rows[] = $world->replace_variables(implode("\t", $row)); + } + + $start = array_search($expected_rows[0], $actual_rows); + + if ( false === $start ) { + throw new \Exception($world->result); + } + + compareTables($expected_rows, array_slice($actual_rows, $start), $output); + } +); + +$steps->Then( + '/^STDOUT should be JSON containing:$/', + function ($world, PyStringNode $expected) { + $output = $world->result->stdout; + $expected = $world->replace_variables((string) $expected); + + if ( ! checkThatJsonStringContainsJsonString($output, $expected) ) { + throw new \Exception($world->result); + } + } +); + +$steps->Then( + '/^STDOUT should be a JSON array containing:$/', + function ($world, PyStringNode $expected) { + $output = $world->result->stdout; + $expected = $world->replace_variables((string) $expected); + + $actualValues = json_decode($output); + $expectedValues = json_decode($expected); + + $missing = array_diff($expectedValues, $actualValues); + if ( ! empty($missing) ) { + throw new \Exception($world->result); + } + } +); + +$steps->Then( + '/^STDOUT should be CSV containing:$/', + function ($world, TableNode $expected) { + $output = $world->result->stdout; + + $expected_rows = $expected->getRows(); + foreach ( $expected as &$row ) { + foreach ( $row as &$value ) { + $value = $world->replace_variables($value); + } + } + + if ( ! checkThatCsvStringContainsValues($output, $expected_rows) ) { + throw new \Exception($world->result); + } + } +); + +$steps->Then( + '/^STDOUT should be YAML containing:$/', + function ($world, PyStringNode $expected) { + $output = $world->result->stdout; + $expected = $world->replace_variables((string) $expected); + + if ( ! checkThatYamlStringContainsYamlString($output, $expected) ) { + throw new \Exception($world->result); + } + } +); + +$steps->Then( + '/^(STDOUT|STDERR) should be empty$/', + function ($world, $stream) { + + $stream = strtolower($stream); + + if ( ! empty($world->result->$stream) ) { + throw new \Exception($world->result); + } + } +); + +$steps->Then( + '/^(STDOUT|STDERR) should not be empty$/', + function ($world, $stream) { + + $stream = strtolower($stream); + + if ( '' === rtrim($world->result->$stream, "\n") ) { + throw new Exception($world->result); + } + } +); + +$steps->Then( + '/^(STDOUT|STDERR) should be a version string (<|<=|>|>=|==|=|!=|<>) ([+\w.{}-]+)$/', + function ($world, $stream, $operator, $goal_ver) { + $goal_ver = $world->replace_variables($goal_ver); + $stream = strtolower($stream); + if ( false === version_compare(trim($world->result->$stream, "\n"), $goal_ver, $operator) ) { + throw new Exception($world->result); + } + } +); + +$steps->Then( + '/(the|the regex) (.+) (file|directory) should (exist|not exist|be:|contain:|not contain:)$/', + function ($world, $strategy, $path, $type, $action, $expected = null) { + $path = $world->replace_variables($path); + + // If it's a relative path, make it relative to the current test dir + if ( '/' !== $path[0] ) { + $path = $world->variables['RUN_DIR'] . "/$path"; + } + + if ( 'file' == $type ) { + if ( 'the regex' === $strategy ) { + $test = 'file_exists_regex'; + } else { + $test = 'file_exists'; + } + } elseif ( 'directory' == $type ) { + $test = 'is_dir'; + } + + switch ( $action ) { + case 'exist': + if ( ! $test($path) ) { + throw new Exception("$path doesn't exist."); + } + break; + case 'not exist': + if ( $test($path) ) { + throw new Exception("$path exists."); + } + break; + default: + if ( ! $test($path) ) { + throw new Exception("$path doesn't exist."); + } + $action = substr($action, 0, -1); + $expected = $world->replace_variables((string) $expected); + if ( 'file' == $type ) { + $contents = file_get_contents($path); + } elseif ( 'directory' == $type ) { + $files = glob(rtrim($path, '/') . '/*'); + foreach ( $files as &$file ) { + $file = str_replace($path . '/', '', $file); + } + $contents = implode(PHP_EOL, $files); + } + $expected_pieces = explode('|AND|', $expected); + foreach ( $expected_pieces as $expected_piece ) { + $expected_piece = trim($expected_piece); + + if ( ! empty($expected_piece) ) { + checkString($contents, $expected_piece, $action); + } + } + } + } +); + +$steps->Then( + '/^an email should (be sent|not be sent)$/', + function ($world, $expected) { + if ( 'be sent' === $expected ) { + assertNotEquals(0, $world->email_sends); + } elseif ( 'not be sent' === $expected ) { + assertEquals(0, $world->email_sends); + } else { + throw new Exception('Invalid expectation'); + } + } +); + +$steps->Then( + '/^the HTTP status code should be (\d+)$/', + function ($world, $return_code) { + $response = \Requests::request('http://localhost:8080'); + assertEquals($return_code, $response->status_code); + } +); diff --git a/inc/site-exporter/mu-migration/features/steps/when.php b/inc/site-exporter/mu-migration/features/steps/when.php new file mode 100644 index 00000000..68994f88 --- /dev/null +++ b/inc/site-exporter/mu-migration/features/steps/when.php @@ -0,0 +1,58 @@ + 'run_check', + 'try' => 'run', + ]; + $method = $map[ $mode ]; + + return $proc->$method(); +} + +function capture_email_sends($stdout) { + $stdout = preg_replace('#WP-CLI test suite: Sent email to.+\n?#', '', $stdout, -1, $email_sends); + return [$stdout, $email_sends]; +} + +$steps->When( + '/^I launch in the background `([^`]+)`$/', + function ($world, $cmd) { + $world->background_proc($cmd); + } +); + +$steps->When( + '/^I (run|try) `([^`]+)`$/', + function ($world, $mode, $cmd) { + $cmd = $world->replace_variables($cmd); + $world->result = invoke_proc($world->proc($cmd), $mode); + list( $world->result->stdout, $world->email_sends ) = capture_email_sends($world->result->stdout); + } +); + +$steps->When( + "/^I (run|try) `([^`]+)` from '([^\s]+)'$/", + function ($world, $mode, $cmd, $subdir) { + $cmd = $world->replace_variables($cmd); + $world->result = invoke_proc($world->proc($cmd, [], $subdir), $mode); + list( $world->result->stdout, $world->email_sends ) = capture_email_sends($world->result->stdout); + } +); + +$steps->When( + '/^I (run|try) the previous command again$/', + function ($world, $mode) { + if ( ! isset($world->result) ) { + throw new \Exception('No previous command.'); + } + + $proc = Process::create($world->result->command, $world->result->cwd, $world->result->env); + $world->result = invoke_proc($proc, $mode); + list( $world->result->stdout, $world->email_sends ) = capture_email_sends($world->result->stdout); + } +); diff --git a/inc/site-exporter/mu-migration/features/tests/csv_matches_user.php b/inc/site-exporter/mu-migration/features/tests/csv_matches_user.php new file mode 100644 index 00000000..8de8a2ae --- /dev/null +++ b/inc/site-exporter/mu-migration/features/tests/csv_matches_user.php @@ -0,0 +1,75 @@ +{$user_id}) ) { + $user_id = (int) $map_file->{$user_id}; + } + $actual_user_data = get_userdata($user_id); + $actual_user_meta = get_user_meta($user_id); + + if ( is_multisite() && ! is_user_member_of_blog($user_id, get_current_blog_id()) ) { + throw new Exception(sprintf('User does not belong to the exported site: %d:%d', $expected_user_data['ID'], $user_id)); + } + + $skip_fields = ['ID', 'user_pass', 'user_registered']; + foreach ( $expected_user_data as $key => $value ) { + // if the user already existed, let's skip some fields + if ( $user_id !== $expected_user_data['ID'] && in_array($key, $skip_fields, true) ) { + continue; + } + if ( isset($actual_user_data->$key) && $actual_user_data->$key != $expected_user_data[ $key ] ) { + throw new Exception( + sprintf( + 'User data does not match: #%d:#%d %s -> %s:%s', + $expected_user_data['ID'], + $user_id, + $key, + $actual_user_data->$key, + $expected_user_data[ $key ] + ) + ); + } + + if ( isset($actual_user_meta[ $key ]) && $actual_user_meta[ $key ][0] != $expected_user_data[ $key ] ) { + throw new Exception( + sprintf( + 'User meta does not match: #%d:#%d %s -> %s:%s', + $expected_user_data['ID'], + $user_id, + $key, + $actual_user_meta[ $key ][0], + $expected_user_data[ $key ] + ) + ); + } + } + } + fclose($handle); + } else { + throw new Exception('Cannot open file'); + } + + echo 'Success'; +} catch ( Exception $e ) { + echo 'Faiure: ' . $e->getMessage(); +} diff --git a/inc/site-exporter/mu-migration/includes/commands/class-mu-migration-base.php b/inc/site-exporter/mu-migration/includes/commands/class-mu-migration-base.php new file mode 100644 index 00000000..8deb69a5 --- /dev/null +++ b/inc/site-exporter/mu-migration/includes/commands/class-mu-migration-base.php @@ -0,0 +1,202 @@ +args = $args + $default_args; + $this->assoc_args = wp_parse_args($assoc_args, $default_assoc_args); + } + + /** + * Runs through all posts and executes the provided callback for each post. + * + * @param array $query_args + * @param callable $callback + * @param bool $verbose + */ + protected function all_posts($query_args, $callback, $verbose = true) { + if ( ! is_callable($callback) ) { + self::error(__('The provided callback is invalid', 'mu-migration')); + } + + $default_args = [ + 'post_type' => 'post', + 'posts_per_page' => 1000, + 'post_status' => ['publish', 'pending', 'draft', 'future', 'private'], + 'cache_results ' => false, + 'update_post_meta_cache' => false, + 'update_post_term_cache' => false, + 'offset' => 0, + ]; + + /** + * Filters the default args for querying posts in the all_posts method. + * + * @since 0.2.0 + * + * @param array $default_args The default args array. + * @return array Default args array. + */ + $default_args = apply_filters('mu-migration/all_posts/default_args', $default_args); + + $query_args = wp_parse_args($query_args, $default_args); + $query = new \WP_Query($query_args); + + $counter = 0; + $found_posts = 0; + while ( $query->have_posts() ) { + $query->the_post(); + + $callback(); + + if ( 0 === $counter ) { + $found_posts = $query->found_posts; + } + + ++$counter; + + if ( 0 === $counter % $query_args['posts_per_page'] ) { + Helpers\stop_the_insanity(); + + $this->log(sprintf(__('Posts Updated: %1$d/%2$d', 'mu-migration'), $counter, $found_posts), true); + $query_args['offset'] += $query_args['posts_per_page']; + $query = new \WP_Query($query_args); + } + } + + wp_reset_postdata(); + + $this->success( + sprintf( + __('%d posts were updated', 'mu-migration'), + $counter + ), + $verbose + ); + } + + /** + * Runs through all records on a specific table. + * + * @param string $message + * @param string $table + * @param callable $callback + * @return bool + */ + protected function all_records($message, $table, $callback) { + global $wpdb; + + $offset = 0; + $step = 1000; + + $found_posts = $wpdb->get_col("SELECT COUNT(ID) FROM {$table}"); + + if ( ! $found_posts ) { + return false; + } + + $found_posts = $found_posts[0]; + + $progress_bar = \WP_CLI\Utils\make_progress_bar(sprintf('[%d] %s', $found_posts, $message), (int) $found_posts, 1); + $progress_bar->display(); + + do { + $results = $wpdb->get_results( + $wpdb->prepare( + "SELECT * FROM {$table} LIMIT %d OFFSET %d", + [ + $step, + $offset, + ] + ) + ); + + if ( $results ) { + foreach ( $results as $result ) { + $callback($result); + $progress_bar->tick(); + } + } + + $offset += $step; + } while ( $results ); + } + + /** + * Outputs a line. + * + * @param string $msg + * @param bool $verbose + */ + protected function line($msg, $verbose) { + if ( $verbose ) { + WP_CLI::line($msg); + } + } + + /** + * Outputs a log message. + * + * @param string $msg + * @param bool $verbose + */ + protected function log($msg, $verbose) { + if ( $verbose ) { + WP_CLI::log($msg); + } + } + + /** + * Outputs a success message. + * + * @param string $msg + * @param bool $verbose + */ + protected function success($msg, $verbose) { + if ( $verbose ) { + WP_CLI::success($msg); + } + } + + /** + * Outputs a warning. + * + * @param string $msg + * @param bool $verbose + */ + protected function warning($msg, $verbose) { + if ( $verbose ) { + WP_CLI::warning($msg); + } + } +} diff --git a/inc/site-exporter/mu-migration/includes/commands/class-mu-migration-export.php b/inc/site-exporter/mu-migration/includes/commands/class-mu-migration-export.php new file mode 100644 index 00000000..47baecd3 --- /dev/null +++ b/inc/site-exporter/mu-migration/includes/commands/class-mu-migration-export.php @@ -0,0 +1,532 @@ + + * : The name of the exported sql file + * + * ## EXAMPLES + * + * wp mu-migration export tables output.sql + * + * @synopsis [--blog_id=] [--tables=] [--non-default-tables=] + * + * @param array $args + * @param array $assoc_args + * @param bool $verbose + */ + public function tables($args = [], $assoc_args = [], $verbose = true) { + global $wpdb; + + $this->process_args( + [ + 0 => '', // output file name + ], + $args, + [ + 'blog_id' => 1, + 'tables' => '', + 'non-default-tables' => '', + ], + $assoc_args + ); + + $filename = $this->args[0]; + + if ( isset($this->assoc_args['blog_id']) ) { + $url = get_home_url((int) $this->assoc_args['blog_id']); + } + + /* + * If the user hasn't supplied the tables he wants to export, let's get them automatically + */ + if ( empty($this->assoc_args['tables']) ) { + $assoc_args = ['format' => 'csv']; + + if ( empty($this->assoc_args['non-default-tables']) && ($this->assoc_args['blog_id'] != 1 || ! is_multisite()) ) { + $assoc_args['all-tables-with-prefix'] = 1; + } + + $tables = Helpers\runcommand('db tables', [], $assoc_args, ['url' => $url]); + + if ( 0 === $tables->return_code ) { + $tables = $tables->stdout; + $tables = explode(',', $tables); + + $tables_to_remove = [ + $wpdb->prefix . 'users', + $wpdb->prefix . 'usermeta', + $wpdb->prefix . 'blog_versions', + $wpdb->prefix . 'blogs', + $wpdb->prefix . 'site', + $wpdb->prefix . 'sitemeta', + $wpdb->prefix . 'registration_log', + $wpdb->prefix . 'signups', + $wpdb->prefix . 'sitecategories', + ]; + + foreach ( $tables as $key => &$table ) { + $table = trim($table); + + if ( in_array($table, $tables_to_remove) ) { + unset($tables[ $key ]); + } + } + } + + if ( ! empty($this->assoc_args['non-default-tables']) ) { + $non_default_tables = explode(',', $this->assoc_args['non-default-tables']); + + $tables = array_unique(array_merge($tables, $non_default_tables)); + } + } else { + // get the user supplied tables list + $tables = explode(',', $this->assoc_args['tables']); + } + + if ( is_array($tables) && ! empty($tables) ) { + $export = Helpers\runcommand('db export', [$filename], ['tables' => implode(',', $tables)]); + + if ( 0 === $export->return_code ) { + $this->success(__('The export is now complete', 'mu-migration'), $verbose); + } else { + \WP_CLI::error(__('Something went wrong while trying to export the database', 'mu-migration')); + } + } else { + \WP_CLI::error(__('Unable to get the list of tables to be exported', 'mu-migration')); + } + } + + /** + * Exports all users to a .csv file. + * + * ## OPTIONS + * + * + * : The name of the exported .csv file + * + * ## EXAMPLES + * + * wp mu-migration export users output.dev --blog_id=2 --woocomerce + * + * @synopsis [--blog_id=] [--woocomerce] + * + * @param array $args + * @param array $assoc_args + * @param bool $verbose + */ + public function users($args = [], $assoc_args = [], $verbose = true) { + $this->process_args( + [ + 0 => 'users.csv', + ], + $args, + [ + 'blog_id' => '', + ], + $assoc_args + ); + + $filename = $this->args[0]; + $delimiter = ','; + + $file_handler = fopen($filename, 'w+'); + + if ( ! $file_handler ) { + \WP_CLI::error(__('Impossible to create the file', 'mu-migration')); + } + + $headers = self::getCSVHeaders(); + + $users_args = [ + 'fields' => 'all', + ]; + + if ( ! empty($this->assoc_args['blog_id']) ) { + $users_args['blog_id'] = (int) $this->assoc_args['blog_id']; + } + + $excluded_meta_keys = [ + 'session_tokens' => true, + 'primary_blog' => true, + 'source_domain' => true, + ]; + + /* + * We don't want meta keys that depends on the db prefix + * + * @see http://stackoverflow.com/a/25316090 + */ + $excluded_meta_keys_regex = [ + '/capabilities$/', + '/user_level$/', + '/dashboard_quick_press_last_post_id$/', + '/user-settings$/', + '/user-settings-time$/', + ]; + + $count = 0; + $users = get_users($users_args); + $user_data_arr = []; + + /* + * This first foreach will pragmatically find all users meta stored in the usersmeta table. + */ + foreach ( $users as $user ) { + $role = isset($user->roles[0]) ? $user->roles[0] : ''; + + $user_data = [ + // General Info. + $user->data->ID, + $user->data->user_login, + $user->data->user_pass, + $user->data->user_nicename, + $user->data->user_email, + $user->data->user_url, + $user->data->user_registered, + $role, + $user->data->user_status, + $user->data->display_name, + + // User Meta. + $user->get('rich_editing'), + $user->get('admin_color'), + $user->get('show_admin_bar_front'), + $user->get('first_name'), + $user->get('last_name'), + $user->get('nickname'), + $user->get('aim'), + $user->get('yim'), + $user->get('jabber'), + $user->get('description'), + ]; + + /* + * Keeping arrays consistent, not all users have the same meta, so it's possible to have some users who + * don't even have a given meta key. We must assure that these users have an empty column for these fields. + */ + if ( count($headers) - count($user_data) > 0 ) { + $user_temp_data_arr = array_fill(0, count($headers) - count($user_data), ''); + $user_data = array_merge($user_data, $user_temp_data_arr); + } + + $user_data = array_combine($headers, $user_data); + + $user_meta = get_user_meta($user->data->ID); + $meta_keys = array_keys($user_meta); + + /* + * Removing all unwanted meta keys. + */ + foreach ( $meta_keys as $user_meta_key ) { + if ( ! isset($excluded_meta_keys[ $user_meta_key ]) ) { + $can_add = true; + + /* + * Checking for unwanted meta keys. + */ + foreach ( $excluded_meta_keys_regex as $regex ) { + if ( preg_match($regex, $user_meta_key) ) { + $can_add = false; + } + } + + if ( ! $can_add ) { + unset($user_meta[ $user_meta_key ]); + } + } else { + unset($user_meta[ $user_meta_key ]); + } + } + + // Get the meta keys again. + $meta_keys = array_keys($user_meta); + + foreach ( $meta_keys as $user_meta_key ) { + $value = $user_meta[ $user_meta_key ]; + + // get_user_meta always return an array whe no $key is passed. + if ( is_array($value) && 1 === count($value) ) { + $value = $value[0]; + } + + // If it's still an array or object, then we need to serialize. + if ( is_array($value) || is_object($value) ) { + $value = serialize($value); + } + + $user_data[ $user_meta_key ] = $value; + } + + // Adding the meta_keys that aren't in the $headers variable to the $headers variable. + $diff = array_diff($meta_keys, $headers); + $headers = array_merge($headers, $diff); + + /** + * Filters the default set of user data to be exported/imported. + * + * @since 0.1.0 + * + * @param array $custom_user_data The custom user data array. + * @param \WP_User $user The user object. + * @return array Array data user. + */ + $custom_user_data = apply_filters('mu_migration/export/user/data', [], $user); + + if ( ! empty($custom_user_data) ) { + $user_data = array_merge($user_data, $custom_user_data); + } + + if ( count(array_values($user_data)) !== count($headers) ) { + \WP_CLI::error(__('The headers and data length are not matching', 'mu-migration')); + } + + $user_data_arr[] = $user_data; + ++$count; + } + + /* + * Now that we have all users meta keys, we can save everything into a csv file. + */ + fputcsv($file_handler, $headers, $delimiter); + + foreach ( $user_data_arr as $user_data ) { + if ( count($headers) - count($user_data) > 0 ) { + $user_temp_data_arr = array_fill(0, count($headers) - count($user_data), ''); + $user_data = array_merge(array_values($user_data), $user_temp_data_arr); + } + fputcsv($file_handler, $user_data, $delimiter); + } + + fclose($file_handler); + + $this->success( + sprintf( + __('%d users have been exported', 'mu-migration'), + absint($count) + ), + $verbose + ); + } + + /** + * Exports the whole site into a zip file. + * + * ## OPTIONS + * + * + * : The name of the exported .zip file + * + * ## EXAMPLES + * + * wp mu-migration export all site.zip + * + * @synopsis [] [--blog_id=] [--tables=] [--non-default-tables=] [--plugins] [--themes] [--uploads] [--verbose] + * + * @param array $args + * @param array $assoc_args + */ + public function all($args = [], $assoc_args = []) { + global $wpdb; + + $switched = false; + + if ( isset($assoc_args['blog_id']) ) { + Helpers\maybe_switch_to_blog((int) $assoc_args['blog_id']); + $switched = true; + } + + $verbose = false; + + if ( isset($assoc_args['verbose']) ) { + $verbose = true; + } + + $site_data = [ + 'url' => esc_url(home_url()), + 'name' => sanitize_text_field(get_bloginfo('name')), + 'admin_email' => sanitize_text_field(get_bloginfo('admin_email')), + 'site_language' => sanitize_text_field(get_bloginfo('language')), + 'db_prefix' => $wpdb->prefix, + 'plugins' => get_plugins(), + 'blog_plugins' => get_option('active_plugins'), + 'network_plugins' => is_multisite() ? get_site_option('active_sitewide_plugins') : [], + 'blog_id' => 1, + ]; + + if ( isset($assoc_args['blog_id']) ) { + $site_data['blog_id'] = get_current_blog_id(); + } + + $this->process_args( + [ + 0 => 'mu-migration-' . sanitize_title($site_data['name']) . '.zip', + ], + $args, + [ + 'blog_id' => false, + 'tables' => '', + 'non-default-tables' => '', + ], + $assoc_args + ); + + $zip_file = $this->args[0]; + + $include_plugins = isset($this->assoc_args['plugins']) ? true : false; + $include_themes = isset($this->assoc_args['themes']) ? true : false; + $include_uploads = isset($this->assoc_args['uploads']) ? true : false; + + $users_assoc_args = []; + $tables_assoc_args = [ + 'tables' => $this->assoc_args['tables'], + 'non-default-tables' => $this->assoc_args['non-default-tables'], + ]; + + if ( $this->assoc_args['blog_id'] ) { + $users_assoc_args['blog_id'] = (int) $this->assoc_args['blog_id']; + $tables_assoc_args['blog_id'] = (int) $this->assoc_args['blog_id']; + } + + $rand = rand(); + + /* + * Adding rand() to the temporary file names to guarantee uniqueness. + */ + $users_file = 'mu-migration-' . $rand . sanitize_title($site_data['name']) . '.csv'; + $tables_file = 'mu-migration-' . $rand . sanitize_title($site_data['name']) . '.sql'; + $meta_data_file = 'mu-migration-' . $rand . sanitize_title($site_data['name']) . '.json'; + + \WP_CLI::log(__('Exporting site meta data...', 'mu-migration')); + file_put_contents($meta_data_file, wp_json_encode($site_data)); + + \WP_CLI::log(__('Exporting users...', 'mu-migration')); + $this->users([$users_file], $users_assoc_args, $verbose); + + \WP_CLI::log(__('Exporting tables', 'mu-migration')); + $this->tables([$tables_file], $tables_assoc_args, $verbose); + + $zip = null; + + /* + * Removing previous $zip_file, if any. + */ + if ( file_exists($zip_file) ) { + unlink($zip_file); + } + + $files_to_zip = [ + $users_file => $users_file, + $tables_file => $tables_file, + $meta_data_file => $meta_data_file, + ]; + + if ( $include_plugins ) { + $files_to_zip['wp-content/plugins'] = WP_PLUGIN_DIR; + } + + if ( $include_themes ) { + $theme_dir = get_template_directory(); + $files_to_zip[ 'wp-content/themes/' . basename($theme_dir) ] = $theme_dir; + if ( get_template_directory() !== get_stylesheet_directory() ) { + $child_theme_dir = get_stylesheet_directory(); + $files_to_zip[ 'wp-content/themes/' . basename($child_theme_dir) ] = $child_theme_dir; + } + } + + if ( $include_uploads ) { + $upload_dir = wp_upload_dir(); + $files_to_zip['wp-content/uploads'] = $upload_dir['basedir']; + } + + try { + \WP_CLI::log(__('Zipping files....', 'mu-migration')); + $zip = Helpers\zip($zip_file, $files_to_zip); + } catch ( \Exception $e ) { + \WP_CLI::warning($e->getMessage()); + } + + if ( file_exists($users_file) ) { + unlink($users_file); + } + + if ( file_exists($tables_file) ) { + unlink($tables_file); + } + + if ( file_exists($meta_data_file) ) { + unlink($meta_data_file); + } + + if ( $zip !== null ) { + \WP_CLI::success(sprintf(__('A zip file named %s has been created', 'mu-migration'), $zip_file)); + } + + if ( $switched ) { + Helpers\maybe_restore_current_blog(); + } + } +} + +\WP_CLI::add_command('mu-migration export', __NAMESPACE__ . '\\ExportCommand'); diff --git a/inc/site-exporter/mu-migration/includes/commands/class-mu-migration-import.php b/inc/site-exporter/mu-migration/includes/commands/class-mu-migration-import.php new file mode 100644 index 00000000..7de11c3a --- /dev/null +++ b/inc/site-exporter/mu-migration/includes/commands/class-mu-migration-import.php @@ -0,0 +1,738 @@ + + * : The name of the exported .csv file + * + * ## EXAMPLES + * + * wp mu-migration import users users.csv --map_file=ids_maps.json + * + * @synopsis --map_file= [--blog_id=] + * + * @param array $args + * @param array $assoc_args + * @param bool $verbose + */ + public function users($args = [], $assoc_args = [], $verbose = true) { + global $wpdb; + + $is_multisite = is_multisite(); + + $this->process_args( + [ + 0 => '', // .csv to import users. + ], + $args, + [ + 'blog_id' => 1, + 'map_file' => 'ids_maps.json', + ], + $assoc_args + ); + + $filename = $this->args[0]; + + if ( empty($filename) || ! file_exists($filename) ) { + WP_CLI::error(__('Invalid input file', 'mu-migration')); + } + + $input_file_handler = fopen($filename, 'r'); + + $delimiter = ','; + + /** + * This array will hold the new id for each old id. + * + * Example: + * array( + * 'OLD_ID' => 'NEW_ID' + * ); + */ + $ids_maps = []; + $labels = []; + $count = 0; + $existing_users = 0; + + if ( false !== $input_file_handler ) { + $this->line(sprintf(__('Parsing %s...', 'mu-migration'), $filename), $verbose); + + $line = 0; + + Helpers\maybe_switch_to_blog($this->assoc_args['blog_id']); + + wp_suspend_cache_addition(true); + while ( false !== ($data = fgetcsv($input_file_handler, 0, $delimiter)) ) { + // Read the labels and skip. + if ( 0 === $line++ ) { + $labels = $data; + continue; + } + + $user_data = array_combine($labels, $data); + + $old_id = $user_data['ID']; + unset($user_data['ID']); + + $user_exists = $wpdb->get_col( + $wpdb->prepare( + "SELECT ID FROM {$wpdb->users} WHERE user_login = %s OR (user_email = %s AND user_email != '');", + $user_data['user_login'], + $user_data['user_email'] + ) + ); + + $user_exists = $user_exists ? $user_exists[0] : false; + + if ( ! $user_exists ) { + + /* + * wp_insert_users accepts only the default user meta keys. + */ + $default_user_data = []; + foreach ( ExportCommand::getCSVHeaders() as $key ) { + if ( isset($user_data[ $key ]) ) { + $default_user_data[ $key ] = $user_data[ $key ]; + } + } + + // All custom user meta data. + $user_meta_data = array_diff_assoc($user_data, $default_user_data); + + $new_id = wp_insert_user($default_user_data); + + if ( ! is_wp_error($new_id) ) { + $wpdb->update($wpdb->users, ['user_pass' => $user_data['user_pass']], ['ID' => $new_id]); + + $user = new \WP_User($new_id); + + // Inserts all custom meta data + foreach ( $user_meta_data as $meta_key => $meta_value ) { + update_user_meta($new_id, $meta_key, maybe_unserialize($meta_value)); + } + + /** + * Fires before exporting the custom user data. + * + * @since 0.1.0 + * + * @param array $user_data The user data array. + * @param \WP_User $user The user object. + */ + do_action('mu_migration/import/user/custom_data_before', $user_data, $user); + + /** + * Ignores it is already documented in + * inc/mu-migration/includes/commands/class-mu-migration-export.php:335. + * + * @ignore + */ + $custom_user_data = apply_filters('mu_migration/export/user/data', [], $user); + + if ( ! empty($custom_user_data) ) { + foreach ( $custom_user_data as $meta_key => $meta_value ) { + if ( isset($user_data[ $meta_key ]) ) { + update_user_meta($new_id, $meta_key, sanitize_text_field($meta_value)); + } + } + } + + /** + * Fires after exporting the custom user data. + * + * @since 0.1.0 + * + * @param array $user_data The user data array. + * @param \WP_User $user The user object. + */ + do_action('mu_migration/import/user/custom_data_after', $user_data, $user); + + ++$count; + $ids_maps[ $old_id ] = $new_id; + if ( $is_multisite ) { + Helpers\light_add_user_to_blog($this->assoc_args['blog_id'], $new_id, $user_data['role']); + } + } else { + $this->warning( + sprintf( + __('An error has occurred when inserting %1$s: %2$s.', 'mu-migration'), + $user_data['user_login'], + implode(', ', $new_id->get_error_messages()) + ), + $verbose + ); + } + } else { + $this->warning( + sprintf( + __('%1$s exists, using his ID (%2$d)...', 'mu-migration'), + $user_data['user_login'], + $user_exists + ), + $verbose + ); + + ++$existing_users; + $ids_maps[ $old_id ] = $user_exists; + if ( $is_multisite ) { + Helpers\light_add_user_to_blog($this->assoc_args['blog_id'], $user_exists, $user_data['role']); + } + } + + unset($user_exists); + unset($user_data); + unset($data); + } + + wp_suspend_cache_addition(false); + + Helpers\maybe_restore_current_blog(); + + if ( ! empty($ids_maps) ) { + // Saving the ids_maps to a file. + $output_file_handler = fopen($this->assoc_args['map_file'], 'w+'); + fwrite($output_file_handler, json_encode($ids_maps)); + fclose($output_file_handler); + + $this->success( + sprintf( + __('A map file has been created: %s', 'mu-migration'), + $this->assoc_args['map_file'] + ), + $verbose + ); + } + + $this->success( + sprintf( + __('%1$d users have been imported and %2$d users already existed', 'mu-migration'), + absint($count), + absint($existing_users) + ), + $verbose + ); + } else { + WP_CLI::error( + sprintf( + __('Can not read the file %s', 'mu-migration'), + $filename + ) + ); + } + } + + /** + * Imports the tables from a single site instance. + * + * This command will perform the search-replace as well as + * the necessary updates to make the new tables work with multisite. + * + * ## OPTIONS + * + * + * : The name of the exported .sql file + * + * ## EXAMPLES + * + * wp mu-migration import tables site.sql --old_prefix=wp_ --old_url=old_domain.com --new_url=new_domain.com + * + * @synopsis --blog_id= --old_prefix= --new_prefix= [--original_blog_id=] [--old_url=] [--new_url=] + * + * @param array $args + * @param array $assoc_args + * @param bool $verbose + */ + public function tables($args = [], $assoc_args = [], $verbose = true) { + global $wpdb, $wu_site_exporter_site_id; + + $this->process_args( + [ + 0 => '', // .sql file to import. + ], + $args, + [ + 'blog_id' => '', + 'old_url' => '', + 'new_url' => '', + 'old_prefix' => $wpdb->prefix, + 'new_prefix' => '', + ], + $assoc_args + ); + + $filename = $this->args[0]; + + if ( empty($filename) || ! file_exists($filename) ) { + WP_CLI::error(__('Invalid input file', 'mu-migration')); + } + + if ( empty($this->assoc_args['blog_id']) ) { + WP_CLI::error(__('Please, provide a blog_id ', 'mu-migration')); + } + + $wu_site_exporter_site_id = $this->assoc_args['blog_id']; + + // Terminates the script if sed is not installed. + $this->check_for_sed_presence(true); + + // Replaces the db prefix and saves back the modifications to the sql file. + if ( ! empty($this->assoc_args['new_prefix']) ) { + $this->replace_db_prefix($filename, $this->assoc_args['old_prefix'], $this->assoc_args['new_prefix']); + } + + $import = Helpers\runcommand('db import', [$filename]); + + if ( 0 === $import->return_code ) { + $this->log(__('Database imported', 'mu-migration'), $verbose); + + // Perform search and replace. + if ( ! empty($this->assoc_args['old_url']) && ! empty($this->assoc_args['new_url']) ) { + $this->log(__('Running search-replace', 'mu-migration'), $verbose); + + $old_url = Helpers\parse_url_for_search_replace($this->assoc_args['old_url']); + $new_url = Helpers\parse_url_for_search_replace($this->assoc_args['new_url']); + + $search_replace = Helpers\launch_self( + 'search-replace', + [ + $old_url, + $new_url, + ], + [], + false, + false, + ['url' => $new_url] + ); + + if ( 0 === $search_replace ) { + $this->log(__('Search and Replace has been successfully executed', 'mu-migration'), $verbose); + } + + $this->log(__('Running Search and Replace for uploads paths', 'mu-migration'), $verbose); + + $from = $to = 'wp-content/uploads'; + + if ( isset($this->assoc_args['original_blog_id']) && $this->assoc_args['original_blog_id'] > 1 ) { + $from = 'wp-content/uploads/sites/' . (int) $this->assoc_args['original_blog_id']; + } + + if ( $this->assoc_args['blog_id'] > 1 ) { + $to = 'wp-content/uploads/sites/' . (int) $this->assoc_args['blog_id']; + } + + if ( $from && $to ) { + $search_replace = Helpers\launch_self( + 'search-replace', + [$from , $to], + [], + false, + false, + ['url' => $new_url] + ); + + if ( 0 === $search_replace ) { + $this->log(sprintf(__('Uploads paths have been successfully updated: %1$s -> %2$s', 'mu-migration'), $from, $to), $verbose); + } + } + } + + Helpers\maybe_switch_to_blog((int) $this->assoc_args['blog_id']); + + // Update the new tables to work properly with multisite. + $new_wp_roles_option_key = $wpdb->prefix . 'user_roles'; + $old_wp_roles_option_key = $this->assoc_args['old_prefix'] . 'user_roles'; + + // Updating user_roles option key. + $wpdb->update( + $wpdb->options, + [ + 'option_name' => $new_wp_roles_option_key, + ], + [ + 'option_name' => $old_wp_roles_option_key, + ], + [ + '%s', + ], + [ + '%s', + ] + ); + + Helpers\maybe_restore_current_blog(); + } + } + + /** + * Imports a new site into multisite from a zip package. + * + * ## OPTIONS + * + * + * : The name of the exported .zip file + * + * ## EXAMPLES + * + * wp mu-migration import all site.zip --uid_fields=_content_audit_owner + * + * @synopsis [--blog_id=] [--new_url=] [--verbose] [--mysql-single-transaction] [--uid_fields=] + * + * @param array $args + * @param array $assoc_args + */ + public function all($args = [], $assoc_args = []) { + $this->process_args( + [], + $args, + [ + 'blog_id' => '', + 'new_url' => '', + 'mysql-single-transaction' => false, + 'uid_fields' => '', + ], + $assoc_args + ); + + $is_multisite = is_multisite(); + + $verbose = false; + + if ( isset($assoc_args['verbose']) ) { + $verbose = true; + } + + $assoc_args = $this->assoc_args; + + $filename = $this->args[0]; + + if ( ! Helpers\is_zip_file($filename) ) { + WP_CLI::error(__('The provided file does not appear to be a zip file', 'mu-migration')); + } + + $temp_dir = 'mu-migration' . time() . '/'; + + WP_CLI::log(__('Extracting zip package...', 'mu-migration')); + + /* + * Extract the file to the $temp_dir + */ + Helpers\extract($filename, $temp_dir); + + /* + * Looks for required (.json, .csv and .sql) files and for the optional folders + * that can live in the zip package (plugins, themes and uploads). + */ + $site_meta_data = glob($temp_dir . '/*.json'); + $users = glob($temp_dir . '/*.csv'); + $sql = glob($temp_dir . '/*.sql'); + $plugins_folder = glob($temp_dir . '/wp-content/plugins'); + $themes_folder = glob($temp_dir . '/wp-content/themes'); + $uploads_folder = glob($temp_dir . '/wp-content/uploads'); + + if ( empty($site_meta_data) || empty($users) || empty($sql) ) { + WP_CLI::error(__("There's something wrong with your zip package, unable to find required files", 'mu-migration')); + } + + $site_meta_data = json_decode(file_get_contents($site_meta_data[0])); + + $old_url = $site_meta_data->url; + + if ( ! empty($assoc_args['new_url']) ) { + $site_meta_data->url = $assoc_args['new_url']; + } + + if ( empty($assoc_args['blog_id']) && $is_multisite ) { + $blog_id = $this->create_new_site($site_meta_data); + } elseif ( $is_multisite ) { + $blog_id = (int) $assoc_args['blog_id']; + } else { + $blog_id = 1; + } + + if ( ! $blog_id ) { + WP_CLI::error(__('Unable to create new site', 'mu-migration')); + } + + $tables_assoc_args = [ + 'blog_id' => $blog_id, + 'original_blog_id' => $site_meta_data->blog_id, + 'old_prefix' => $site_meta_data->db_prefix, + 'new_prefix' => Helpers\get_db_prefix($blog_id), + ]; + + /* + * If changing URL, then set the proper params to force search-replace in the tables method. + */ + if ( ! empty($assoc_args['new_url']) ) { + $tables_assoc_args['new_url'] = esc_url($assoc_args['new_url']); + $tables_assoc_args['old_url'] = esc_url($old_url); + } + + WP_CLI::log(__('Importing tables...', 'mu-migration')); + + /* + * If the flag --mysql-single-transaction is passed, then the SQL is wrapped with + * START TRANSACTION and COMMIT to insert in one single transaction. + */ + if ( $assoc_args['mysql-single-transaction'] ) { + Helpers\addTransaction($sql[0]); + } + + $this->tables([$sql[0]], $tables_assoc_args, $verbose); + + $map_file = $temp_dir . '/users_map.json'; + + $users_assoc_args = [ + 'map_file' => $map_file, + 'blog_id' => $blog_id, + ]; + + WP_CLI::log(__('Moving files...', 'mu-migration')); + + if ( ! empty($plugins_folder) ) { + $blog_plugins = isset($site_meta_data->blog_plugins) ? (array) $site_meta_data->blog_plugins : false; + $network_plugins = isset($site_meta_data->network_plugins) ? array_keys((array) $site_meta_data->network_plugins) : false; + $this->move_and_activate_plugins($plugins_folder[0], (array) $site_meta_data->plugins, $blog_plugins, $network_plugins); + } + + if ( ! empty($uploads_folder) ) { + $this->move_uploads($uploads_folder[0], $blog_id); + } + + if ( ! empty($themes_folder) ) { + $this->move_themes($themes_folder[0]); + } + + WP_CLI::log(__('Importing Users...', 'mu-migration')); + + $this->users([$users[0]], $users_assoc_args, $verbose); + + if ( file_exists($map_file) ) { + $postsCommand = new PostsCommand(); + + $postsCommand->update_author( + [$map_file], + [ + 'blog_id' => $blog_id, + 'uid_fields' => $assoc_args['uid_fields'], + ], + $verbose + ); + } + + WP_CLI::log(__('Flushing rewrite rules...', 'mu-migration')); + + add_action( + 'init', + function () use ($blog_id) { + /* + * Flush the rewrite rules for the newly created site, just in case. + */ + Helpers\maybe_switch_to_blog($blog_id); + flush_rewrite_rules(); + Helpers\maybe_restore_current_blog(); + }, + 9999 + ); + + WP_CLI::log(__('Removing temporary files....', 'mu-migration')); + + Helpers\delete_folder($temp_dir); + + WP_CLI::success( + sprintf( + __('All done, your new site is available at %s. Remember to flush the cache (memcache, redis etc).', 'mu-migration'), + esc_url($site_meta_data->url) + ) + ); + } + + /** + * Moves the plugins to the right location. + * + * @param string $plugins_dir + * @param array|bool $blog_plguins + * @param array|bool $network_plugins + */ + private function move_and_activate_plugins($plugins_dir, $plugins, $blog_plugins, $network_plugins) { + if ( file_exists($plugins_dir) ) { + WP_CLI::log(__('Moving Plugins...', 'mu-migration')); + $installed_plugins = WP_PLUGIN_DIR; + $check_plugins = false !== $blog_plugins && false !== $network_plugins; + foreach ( $plugins as $plugin_name => $plugin ) { + $plugin_folder = dirname($plugin_name); + $fullPluginPath = $plugins_dir . '/' . $plugin_folder; + + if ( $check_plugins && ! in_array($plugin_name, $blog_plugins, true) && + ! in_array($plugin_name, $network_plugins, true) ) { + continue; + } + + if ( ! file_exists($installed_plugins . '/' . $plugin_folder) ) { + WP_CLI::log(sprintf(__('Moving %s to plugins folder'), $plugin_name)); + rename($fullPluginPath, $installed_plugins . '/' . $plugin_folder); + } + + if ( $check_plugins && in_array($plugin_name, $blog_plugins, true) ) { + WP_CLI::log(sprintf(__('Activating plugin: %s '), $plugin_name)); + activate_plugin($installed_plugins . '/' . $plugin_name); + } elseif ( $check_plugins && in_array($plugin_name, $network_plugins, true) ) { + WP_CLI::log(sprintf(__('Activating plugin network-wide: %s '), $plugin_name)); + activate_plugin($installed_plugins . '/' . $plugin_name, '', true); + } + } + } + } + + /** + * Moves the uploads folder to the right location. + * + * @param string $uploads_dir + * @param int $blog_id + */ + private function move_uploads($uploads_dir, $blog_id) { + if ( file_exists($uploads_dir) ) { + \WP_CLI::log(__('Moving Uploads...', 'mu-migration')); + Helpers\maybe_switch_to_blog($blog_id); + $dest_uploads_dir = wp_upload_dir(); + Helpers\maybe_restore_current_blog(); + + Helpers\move_folder($uploads_dir, $dest_uploads_dir['basedir']); + } + } + + /** + * Moves the themes to the right location. + * + * @param string $themes_dir + */ + private function move_themes($themes_dir) { + if ( file_exists($themes_dir) ) { + WP_CLI::log(__('Moving Themes...', 'mu-migration')); + $themes = new \DirectoryIterator($themes_dir); + $installed_themes = get_theme_root(); + + foreach ( $themes as $theme ) { + if ( $theme->isDir() ) { + $fullPluginPath = $themes_dir . '/' . $theme->getFilename(); + + if ( ! file_exists($installed_themes . '/' . $theme->getFilename()) ) { + WP_CLI::log(sprintf(__('Moving %s to themes folder'), $theme->getFilename())); + rename($fullPluginPath, $installed_themes . '/' . $theme->getFilename()); + + Helpers\runcommand('theme enable', [$theme->getFilename()]); + } + } + } + } + } + + /** + * Creates a new site within multisite. + * + * @param object $meta_data + * @return bool|false|int + */ + private function create_new_site($meta_data) { + $parsed_url = parse_url(esc_url($meta_data->url)); + $site_id = get_main_network_id(); + + $parsed_url['path'] = isset($parsed_url['path']) ? $parsed_url['path'] : '/'; + + if ( domain_exists($parsed_url['host'], $parsed_url['path'], $site_id) ) { + return false; + } + + $blog_id = wp_insert_site( + [ + 'domain' => $parsed_url['host'], + 'path' => $parsed_url['path'], + 'network_id' => $site_id, + ] + ); + + if ( ! $blog_id ) { + return false; + } + + return $blog_id; + } + + /** + * Replaces the db_prefix with a new one using sed. + * + * @param string $filename The filename of the sql file to which the db prefix should be replaced. + * @param string $old_db_prefix The db prefix to be replaced. + * @param string $new_db_prefix The new db prefix. + */ + private function replace_db_prefix($filename, $old_db_prefix, $new_db_prefix) { + $new_prefix = $new_db_prefix; + + if ( ! empty($new_prefix) ) { + $mysql_chunks_regex = [ + 'DROP TABLE IF EXISTS', + 'CREATE TABLE', + 'LOCK TABLES', + 'INSERT INTO', + 'CREATE TABLE IF NOT EXISTS', + 'ALTER TABLE', + 'CONSTRAINT', + 'REFERENCES', + ]; + + // build sed expressions + $sed_commands = []; + foreach ( $mysql_chunks_regex as $regex ) { + $sed_commands[] = "s/{$regex} `{$old_db_prefix}/{$regex} `{$new_prefix}/g"; + } + + foreach ( $sed_commands as $sed_command ) { + $full_command = "sed '$sed_command' -i $filename"; + $sed_result = \WP_CLI::launch($full_command, false, false); + + if ( 0 !== $sed_result ) { + \WP_CLI::warning(__('Something went wrong while running sed', 'mu-migration')); + } + } + } + } + + /** + * Checks whether sed is available or not. + * + * @param bool $exit_on_error If set to true the script will be terminated if sed is not available. + * @return bool + */ + private function check_for_sed_presence($exit_on_error = false) { + $sed = \WP_CLI::launch('echo "wp_" | sed "s/wp_/wp_5_/g"', false, true); + + if ( 'wp_5_' !== trim($sed->stdout, "\x0A") ) { + if ( $exit_on_error ) { + \WP_CLI::error(__('sed not present, please install sed', 'mu-migration')); + } + + return false; + } + + return true; + } +} + +WP_CLI::add_command('mu-migration import', __NAMESPACE__ . '\\ImportCommand'); diff --git a/inc/site-exporter/mu-migration/includes/commands/class-mu-migration-posts.php b/inc/site-exporter/mu-migration/includes/commands/class-mu-migration-posts.php new file mode 100644 index 00000000..1b60bb13 --- /dev/null +++ b/inc/site-exporter/mu-migration/includes/commands/class-mu-migration-posts.php @@ -0,0 +1,179 @@ + + * : The name of the json map file + * + * ## EXAMPLES + * + * wp mu-migration posts update_author map_users.json --blog_id=2 --uid_fields=_content_audit_owner + * + * @synopsis --blog_id= [--uid_fields=] + * + * @param array $args + * @param array $assoc_args + * @param bool $verbose + */ + public function update_author($args = [], $assoc_args = [], $verbose = true) { + global $wpdb; + + $this->process_args( + [ + 0 => '', // .json map file + ], + $args, + [ + 'blog_id' => '', + 'uid_fields' => '', + ], + $assoc_args + ); + + $filename = $this->args[0]; + + $is_multisite = is_multisite(); + + if ( empty($filename) || ! file_exists($filename) ) { + WP_CLI::error(__('Invalid input file', 'mu-migration')); + } + + if ( $is_multisite ) { + switch_to_blog((int) $this->assoc_args['blog_id']); + } + + $is_woocommerce = Helpers\is_woocommerce_active(); + + $ids_map = json_decode(file_get_contents($filename)); + + if ( null === $ids_map ) { + WP_CLI::error( + __('An error has occurred when parsing the json file', 'mu-migration') + ); + } + + $equals_id = []; + $author_not_found = []; + + $this->all_records( + __('Updating posts authors', 'mu-migration'), + $wpdb->posts, + function ($result) use (&$equals_id, &$author_not_found, $ids_map, $verbose, $is_woocommerce) { + $author = $result->post_author; + + if ( isset($ids_map->{$author}) ) { + if ( $author != $ids_map->{$author} ) { + global $wpdb; + + $wpdb->update( + $wpdb->posts, + ['post_author' => $ids_map->{$author}], + ['ID' => $result->ID], + ['%d'], + ['%d'] + ); + + $this->log( + sprintf( + __('Updated post_author for "%1$s" (ID #%2$d)', 'mu-migration'), + $result->post_title, + absint($result->ID) + ), + $verbose + ); + } else { + $this->log( + sprintf( + __('#%d New user ID equals to the old user ID'), + $result->ID + ), + $verbose + ); + $equals_id[] = absint($result->ID); + } + } else { + $this->log( + sprintf( + __("#%d New user ID not found or it's already been updated", 'mu-migration'), + absint($result->ID) + ), + $verbose + ); + + $author_not_found[] = absint($result->ID); + } + + // Parse uid_fields + $uid_fields = explode(',', $this->assoc_args['uid_fields']); + // Automatically add Woocommerce user id field + if ( $is_woocommerce ) { + $uid_fields[] = '_customer_user'; + } + // Iterate over fields and update them. + foreach ( array_filter($uid_fields) as $f ) { + $f = trim($f); + $old_user = get_post_meta((int) $result->ID, $f, true); + + if ( isset($ids_map->{$old_user}) && $old_user != $ids_map->{$old_user} ) { + $new_user = $ids_map->{$old_user}; + + update_post_meta((int) $result->ID, $f, $new_user); + + $this->log( + sprintf( + __('Updated %1$s for "%2$s" (ID #%3$d)', 'mu-migration'), + $f, + $result->post_title, + absint($result->ID) + ), + $verbose + ); + } + } + } + ); + + // Report. + if ( ! empty($author_not_found) ) { + $this->warning( + sprintf( + __('%1$d records failed to update its post_author: %2$s', 'mu-migration'), + count($author_not_found), + implode(',', $author_not_found) + ), + $verbose + ); + } + + if ( ! empty($equals_id) ) { + $this->warning( + sprintf( + __('The following records have the new ID equal to the old ID: %s', 'mu-migration'), + implode(',', $equals_id) + ), + $verbose + ); + } + + if ( $is_multisite ) { + restore_current_blog(); + } + } +} + +WP_CLI::add_command('mu-migration posts', __NAMESPACE__ . '\\PostsCommand'); diff --git a/inc/site-exporter/mu-migration/includes/commands/class-mu-migration-users.php b/inc/site-exporter/mu-migration/includes/commands/class-mu-migration-users.php new file mode 100644 index 00000000..189f1c15 --- /dev/null +++ b/inc/site-exporter/mu-migration/includes/commands/class-mu-migration-users.php @@ -0,0 +1,159 @@ + + * : The new password for the users set + * + * ## EXAMPLES + * + * wp mu-migration users update_passwords --reset --blog_id=2 --send_email + * + * @synopsis [] [--blog_id=] [--reset] [--send_email] [--include=] [--exclude=] + * + * @param array $args + * @param array $assoc_args + */ + public function update_passwords($args = [], $assoc_args = []) { + $this->process_args( + [ + 0 => '', // New password. + ], + $args, + [ + 'blog_id' => '', + 'role' => '', + 'exclude' => '', + 'include' => '', + ], + $assoc_args + ); + + $new_password = $this->args[0]; + + $reset_passwords = false; + + if ( isset($this->assoc_args['reset']) ) { + $reset_passwords = true; + } + + if ( ! $reset_passwords && empty($new_password) ) { + WP_CLI::error(__('Please, provide a new password for the users', 'mu-migration')); + } + + $send_email = false; + + if ( isset($this->assoc_args['send_email']) ) { + $send_email = true; + } + + $users_args = [ + 'fields' => 'all', + 'role' => $this->assoc_args['role'], + 'include' => ! empty($this->assoc_args['include']) ? explode(',', $this->assoc_args['include']) : [], + 'exclude' => ! empty($this->assoc_args['exclude']) ? explode(',', $this->assoc_args['exclude']) : [], + ]; + + if ( ! empty($this->assoc_args['blog_id']) ) { + $users_args['blog_id'] = (int) $this->assoc_args['blog_id']; + } + + $users = get_users($users_args); + + foreach ( $users as $user ) { + if ( $reset_passwords ) { + $new_password = wp_generate_password(12, false); + } + + wp_set_password($new_password, $user->data->ID); + + WP_CLI::log(sprintf(__('Password updated for user #%1$d:%2$s', 'mu-migration'), $user->data->ID, $user->data->user_login)); + + if ( $send_email ) { + $this->send_reset_link($user->data); + } + } + } + + /** + * Handles sending password retrieval email to user (based on retrieve_password). + * + * @param $user_data + * @return bool|\WP_Error + */ + private function send_reset_link($user_data) { + + $user_login = $user_data->user_login; + $user_email = $user_data->user_email; + $key = get_password_reset_key($user_data); + + if ( is_wp_error($key) ) { + return $key; + } + + $message = __('A password reset has been requested for the following account:') . "\r\n\r\n"; + $message .= network_home_url('/') . "\r\n\r\n"; + $message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n"; + $message .= __('In order to log in again you have to reset your password.') . "\r\n\r\n"; + $message .= __('To reset your password, visit the following address:') . "\r\n\r\n"; + $message .= '<' . network_site_url("wp-login.php?action=rp&key=$key&login=" . rawurlencode($user_login), 'login') . ">\r\n"; + + if ( is_multisite() ) { + $blogname = $GLOBALS['current_site']->site_name; + } else { + /* + * The blogname option is escaped with esc_html on the way into the database + * in sanitize_option we want to reverse this for the plain text arena of emails. + */ + $blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES); + } + + $title = sprintf(__('[%s] Password Reset'), $blogname); + + /** + * Filters the subject of the password reset email. + * + * @since 2.8.0 + * @since 4.4.0 Added the `$user_login` and `$user_data` parameters. + * + * @param string $title Default email title. + * @param string $user_login The username for the user. + * @param \WP_User $user_data WP_User object. + * @return string Default email title. + */ + $title = apply_filters('retrieve_password_title', $title, $user_login, $user_data); + + /** + * Filters the message body of the password reset mail. + * + * @since 2.8.0 + * @since 4.1.0 Added `$user_login` and `$user_data` parameters. + * + * @param string $message Default mail message. + * @param string $key The activation key. + * @param string $user_login The username for the user. + * @param \WP_User $user_data WP_User object. + * @return string Default mail message. + */ + $message = apply_filters('retrieve_password_message', $message, $key, $user_login, $user_data); + + if ( $message && ! wp_mail($user_email, wp_specialchars_decode($title), $message) ) { + WP_CLI::log(__('The email could not be sent', 'mu-migration')); + } + + return true; + } +} + +WP_CLI::add_command('mu-migration users', __NAMESPACE__ . '\\UsersCommand'); diff --git a/inc/site-exporter/mu-migration/includes/commands/class-mu-migration.php b/inc/site-exporter/mu-migration/includes/commands/class-mu-migration.php new file mode 100644 index 00000000..2a7246bb --- /dev/null +++ b/inc/site-exporter/mu-migration/includes/commands/class-mu-migration.php @@ -0,0 +1,26 @@ +isFile() ? @unlink($path->getPathname()) : @rmdir($path->getPathname()); + } + + if ( $deleteParent ) { + rmdir($dirPath); + } + } +} + +/** + * Recursively copies a directory and its files. + * + * @param string $source + * @param string $dest + */ +function move_folder($source, $dest) { + if ( ! file_exists($dest) ) { + mkdir($dest); + } + + foreach ( + $iterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($source, \RecursiveDirectoryIterator::SKIP_DOTS), + \RecursiveIteratorIterator::SELF_FIRST + ) as $item + ) { + if ( $item->isDir() ) { + $dir = $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName(); + if ( ! file_exists($dir) ) { + mkdir($dir); + } + } else { + $dest_file = $dest . DIRECTORY_SEPARATOR . $iterator->getSubPathName(); + if ( ! file_exists($dest_file) ) { + rename($item, $dest_file); + } + } + } +} + +/** + * Retrieves the db prefix based on the $blog_id. + * + * @uses wpdb + * + * @param int $blog_id + * @return string + */ +function get_db_prefix($blog_id) { + global $wpdb; + + if ( $blog_id > 1 ) { + $new_db_prefix = $wpdb->base_prefix . $blog_id . '_'; + } else { + $new_db_prefix = $wpdb->prefix; + } + + return $new_db_prefix; +} + +/** + * Does the same thing that add_user_to_blog does, but without calling switch_to_blog(). + * + * @param int $blog_id + * @param int $user_id + * @param string $role + * @return \WP_Error + */ +function light_add_user_to_blog($blog_id, $user_id, $role) { + $user = get_userdata($user_id); + + if ( ! $user ) { + restore_current_blog(); + return new \WP_Error('user_does_not_exist', __('The requested user does not exist.')); + } + + if ( ! get_user_meta($user_id, 'primary_blog', true) ) { + update_user_meta($user_id, 'primary_blog', $blog_id); + $details = get_blog_details($blog_id); + update_user_meta($user_id, 'source_domain', $details->domain); + } + + $user->set_role($role); + + /** + * Fires immediately after a user is added to a site. + * + * @since MU + * + * @param int $user_id User ID. + * @param string $role User role. + * @param int $blog_id Blog ID. + */ + do_action('add_user_to_blog', $user_id, $role, $blog_id); + wp_cache_delete($user_id, 'users'); + wp_cache_delete($blog_id . '_user_count', 'blog-details'); +} + +/** + * Frees up memory for long running processes. + */ +function stop_the_insanity() { + global $wpdb, $wp_actions, $wp_filter, $wp_object_cache; + + // reset queries + $wpdb->queries = []; + // Prevent wp_actions from growing out of control + $wp_actions = []; + + if ( is_object($wp_object_cache) ) { + $wp_object_cache->group_ops = []; + $wp_object_cache->stats = []; + $wp_object_cache->memcache_debug = []; + $wp_object_cache->cache = []; + + if ( method_exists($wp_object_cache, '__remoteset') ) { + $wp_object_cache->__remoteset(); + } + } + + /* + * The WP_Query class hooks a reference to one of its own methods + * onto filters if update_post_term_cache or + * update_post_meta_cache are true, which prevents PHP's garbage + * collector from cleaning up the WP_Query instance on long- + * running processes. + * + * By manually removing these callbacks (often created by things + * like get_posts()), we're able to properly unallocate memory + * once occupied by a WP_Query object. + * + */ + if ( isset($wp_filter['get_term_metadata']) ) { + /* + * WordPress 4.7 has a new Hook infrastructure, so we need to make sure + * we're accessing the global array properly. + */ + if ( class_exists('WP_Hook') && $wp_filter['get_term_metadata'] instanceof \WP_Hook ) { + $filter_callbacks = &$wp_filter['get_term_metadata']->callbacks; + } else { + $filter_callbacks = &$wp_filter['get_term_metadata']; + } + + if ( isset($filter_callbacks[10]) ) { + foreach ( $filter_callbacks[10] as $hook => $content ) { + if ( preg_match('#^[0-9a-f]{32}lazyload_term_meta$#', $hook) ) { + unset($filter_callbacks[10][ $hook ]); + } + } + } + } +} + +/** + * Add START TRANSACTION and COMMIT to the sql export. + * shamelessly stolen from http://stackoverflow.com/questions/1760525/need-to-write-at-beginning-of-file-with-php + * + * @param string $orig_filename SQL dump file name. + */ +function addTransaction($orig_filename) { + $context = stream_context_create(); + $orig_file = fopen($orig_filename, 'r', 1, $context); + + $temp_filename = tempnam(sys_get_temp_dir(), 'php_prepend_'); + file_put_contents($temp_filename, 'START TRANSACTION;' . PHP_EOL); + file_put_contents($temp_filename, $orig_file, FILE_APPEND); + file_put_contents($temp_filename, 'COMMIT;', FILE_APPEND); + + fclose($orig_file); + unlink($orig_filename); + rename($temp_filename, $orig_filename); +} + +/** + * Switches to another blog if on Multisite + * + * @param $blog_id + */ +function maybe_switch_to_blog($blog_id) { + if ( is_multisite() ) { + switch_to_blog($blog_id); + } +} + +/** + * Restore the current blog if on multisite + */ +function maybe_restore_current_blog() { + if ( is_multisite() ) { + restore_current_blog(); + } +} + + +/** + * Extracts a zip file to the $dest_dir. + * + * @uses Zippy + * + * @param string $filename + * @param string $dest_dir + */ +function extract($filename, $dest_dir) { + $zippy = Zippy::load(); + + $site_package = $zippy->open($filename); + mkdir($dest_dir); + $site_package->extract($dest_dir); +} + +/** + * Creates a zip files with the provided files/folder to zip + * + * @param string $zip_files The name of the zip file + * @param array $files_to_zip The files to include in the zip file + * + * @return void + */ +function zip($zip_file, $files_to_zip) { + $files_to_zip = apply_filters('wu_site_exporter_files_to_zip', $files_to_zip); + return Zippy::load()->create($zip_file, $files_to_zip, true); +} + +/** + * Run a command within WP_CLI + * + * @param string $command The command to run + * @param array $args The command arguments + * @param array $assoc_args The associative arguments + * @param array $global_args The global arguments + * + * @return object Result object with stdout, stderr, and return_code properties + */ +function runcommand($command, $args = [], $assoc_args = [], $global_args = []) { + global $wpdb, $wu_site_exporter_site_id; + + $assoc_args = array_merge($assoc_args, $global_args); + + $transformed_assoc_args = []; + + foreach ( $assoc_args as $key => $arg ) { + $transformed_assoc_args[] = '--' . $key . '=' . $arg; + } + $params = sprintf('%s %s', implode(' ', $args), implode(' ', $transformed_assoc_args)); + + $full_command = sprintf('%s %s', $command, $params); + + /** + * If we're in CLI context with real WP-CLI available, use it. + * Otherwise, use pure PHP implementation for web/AJAX context. + */ + if (PHP_SAPI === 'cli' && class_exists('\WP_CLI') && method_exists('\WP_CLI', 'runcommand')) { + $options = [ + 'return' => 'all', + 'launch' => false, + 'exit_error' => false, + ]; + return \WP_CLI::runcommand($full_command, $options); + } + + /** + * Web/AJAX context - implement commands using pure PHP + * This is the polyfill implementation that works without WP-CLI + */ + $stdout = ''; + + if (strpos($full_command, 'db tables') === 0) { + // Get list of tables for the current site + $sql = $wpdb->prepare('SHOW TABLES LIKE %s', $wpdb->esc_like($wpdb->prefix) . '%'); + $results = $wpdb->get_col($sql); // phpcs:ignore + $stdout = implode(',', $results); + } elseif (strpos($full_command, 'db export') === 0) { + // Export database using mysqldump-php + $table_list = []; + preg_match('/--tables=(.+)/', $full_command, $table_list); + + $dump = new \Ifsnop\Mysqldump\Mysqldump( + sprintf('mysql:dbname=%s;host=%s', DB_NAME, DB_HOST), + DB_USER, + DB_PASSWORD, + [ + 'compress' => \Ifsnop\Mysqldump\Mysqldump::NONE, + 'include-tables' => explode(',', $table_list[1]), + ] + ); + + $file_name = str_replace('db export', '', $full_command); + $file_name = preg_replace('/--tables=(.+)/', '', $file_name); + $file_name = trim($file_name); + + $dump->start($file_name); + } elseif (strpos($full_command, 'db import') === 0) { + // Import database using custom importer + $file_name = str_replace('db import', '', $full_command); + $file_name = trim($file_name); + + $import = new \WP_Ultimo\Site_Exporter\Database\Import( + $file_name, + DB_USER, + DB_PASSWORD, + DB_NAME, + DB_HOST, + true, // drop_tables + true, // force_drop_tables + $wu_site_exporter_site_id + ); + } + + return (object) [ + 'stdout' => $stdout, + 'stderr' => '', + 'return_code' => 0, + ]; +} + +/** + * Run a WP-CLI command in the same process (launch_self wrapper) + * + * @param string $command WP-CLI command to call + * @param array $args Positional arguments + * @param array $assoc_args Associative arguments + * @param bool $exit_on_error Whether to exit if command returns elevated return code + * @param bool $return_detailed Whether to return exit status or detailed results + * @param array $runtime_args Override global args (path, url, user, allow-root) + * + * @return int Return code (0 for success) + */ +function launch_self($command, $args = [], $assoc_args = [], $exit_on_error = true, $return_detailed = false, $runtime_args = []) { + global $wpdb, $wu_site_exporter_site_id; + + /** + * If we're in CLI context with real WP-CLI available, use it + */ + if (PHP_SAPI === 'cli' && class_exists('\WP_CLI') && method_exists('\WP_CLI', 'launch_self')) { + return \WP_CLI::launch_self($command, $args, $assoc_args, $exit_on_error, $return_detailed, $runtime_args); + } + + /** + * Web/AJAX context - implement commands using pure PHP + */ + if ($command === 'search-replace') { + $search = $args[0]; + $replace = $args[1]; + + $site = is_multisite() ? get_site($wu_site_exporter_site_id) : (object) [ + 'blog_id' => 1, + ]; + + if (! $site) { + return 1; + } + + $max_execution = new \WP_Ultimo\Site_Exporter\Database\Max_Execution_Time(); + $dbm = new \WP_Ultimo\Site_Exporter\Database\Manager($wpdb); + $replacer = new \WP_Ultimo\Site_Exporter\Database\Replace($dbm, $max_execution); + $tables = $dbm->get_tables($site->blog_id); + + $replacer->set_dry_run(false); + + $report = $replacer->run_search_replace($search, $replace, $tables); + + if (is_wp_error($report)) { + error_log('Site Exporter Error: ' . $report->get_error_message()); + return 1; + } elseif (count($report['changes']) === 0) { + error_log('Site Exporter Warning: Search pattern not found'); + } + + return 0; + } elseif ($command === 'theme enable') { + if (isset($args[0])) { + switch_theme($args[0]); + } + return 0; + } + + // Unknown command + return 1; +} diff --git a/inc/site-exporter/mu-migration/mu-migration.php b/inc/site-exporter/mu-migration/mu-migration.php new file mode 100644 index 00000000..4e0a4dba --- /dev/null +++ b/inc/site-exporter/mu-migration/mu-migration.php @@ -0,0 +1,40 @@ += 7.1'); +} + +if ( file_exists(__DIR__ . '/vendor/autoload.php') ) { + require_once 'vendor/autoload.php'; +} + +require_once 'includes/helpers.php'; + +require_once TENUP_MU_MIGRATION_COMMANDS_PATH . 'class-mu-migration.php'; +require_once TENUP_MU_MIGRATION_COMMANDS_PATH . 'class-mu-migration-base.php'; +require_once TENUP_MU_MIGRATION_COMMANDS_PATH . 'class-mu-migration-export.php'; +require_once TENUP_MU_MIGRATION_COMMANDS_PATH . 'class-mu-migration-import.php'; +require_once TENUP_MU_MIGRATION_COMMANDS_PATH . 'class-mu-migration-posts.php'; +require_once TENUP_MU_MIGRATION_COMMANDS_PATH . 'class-mu-migration-users.php'; diff --git a/inc/site-exporter/mu-migration/utils/behat-tags.php b/inc/site-exporter/mu-migration/utils/behat-tags.php new file mode 100644 index 00000000..0f8990c5 --- /dev/null +++ b/inc/site-exporter/mu-migration/utils/behat-tags.php @@ -0,0 +1,75 @@ +') +); + +// Skip Github API tests by default because of rate limiting. See https://github.com/wp-cli/wp-cli/issues/1612 +$skip_tags[] = '@github-api'; + +// Skip tests known to be broken. +$skip_tags[] = '@broken'; + +// Require PHP extension, eg 'imagick'. +function extension_tags() { + $extension_tags = []; + exec("grep '@require-extension-[A-Za-z_]*' -h -o features/*.feature | uniq", $extension_tags); + + $skip_tags = []; + + $substr_start = strlen('@require-extension-'); + foreach ( $extension_tags as $tag ) { + $extension = substr($tag, $substr_start); + if ( ! extension_loaded($extension) ) { + $skip_tags[] = $tag; + } + } + + return $skip_tags; +} + +$skip_tags = array_merge($skip_tags, extension_tags()); + +if ( ! empty($skip_tags) ) { + echo '--tags=~' . implode('&&~', $skip_tags); +} diff --git a/inc/sso/class-admin-bar-magic-links.php b/inc/sso/class-admin-bar-magic-links.php index a21195ea..318beda8 100644 --- a/inc/sso/class-admin-bar-magic-links.php +++ b/inc/sso/class-admin-bar-magic-links.php @@ -108,7 +108,7 @@ public function show_access_denied_with_magic_links(): void { wp_die( sprintf( /* translators: 1: Site title. */ - __('You attempted to access the "%1$s" dashboard, but you do not currently have privileges on this site. If you believe you should be able to access the "%1$s" dashboard, please contact your network administrator.'), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + __('You attempted to access the "%1$s" dashboard, but you do not currently have privileges on this site. If you believe you should be able to access the "%1$s" dashboard, please contact your network administrator.', 'ultimate-multisite'), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped $blog_name // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ), 403 @@ -122,12 +122,12 @@ public function show_access_denied_with_magic_links(): void { $output = '

    ' . sprintf( /* translators: 1: Site title. */ - __('You attempted to access the "%1$s" dashboard, but you do not currently have privileges on this site. If you believe you should be able to access the "%1$s" dashboard, please contact your network administrator.'), + __('You attempted to access the "%1$s" dashboard, but you do not currently have privileges on this site. If you believe you should be able to access the "%1$s" dashboard, please contact your network administrator.', 'ultimate-multisite'), $blog_name ) . '

    '; - $output .= '

    ' . __('If you reached this screen by accident and meant to visit one of your own sites, here are some shortcuts to help you find your way.') . '

    '; + $output .= '

    ' . __('If you reached this screen by accident and meant to visit one of your own sites, here are some shortcuts to help you find your way.', 'ultimate-multisite') . '

    '; - $output .= '

    ' . __('Your Sites') . '

    '; + $output .= '

    ' . __('Your Sites', 'ultimate-multisite') . '

    '; $output .= ''; foreach ( $blogs as $blog ) { @@ -141,8 +141,8 @@ public function show_access_denied_with_magic_links(): void { $output .= ''; $output .= ''; - $output .= ''; + $output .= ''; $output .= ''; } diff --git a/inc/tax/class-dashboard-taxes-tab.php b/inc/tax/class-dashboard-taxes-tab.php index 727bab61..4693f421 100644 --- a/inc/tax/class-dashboard-taxes-tab.php +++ b/inc/tax/class-dashboard-taxes-tab.php @@ -103,7 +103,7 @@ public function add_back_link($links) { $back_link = [ [ - 'url' => wu_network_admin_url('wp-ultimo'), + 'url' => wu_network_admin_url('ultimate-multisite'), 'label' => __('Go Back', 'ultimate-multisite'), 'icon' => 'wu-reply', ], diff --git a/inc/template-library/class-api-client.php b/inc/template-library/class-api-client.php new file mode 100644 index 00000000..68755e6a --- /dev/null +++ b/inc/template-library/class-api-client.php @@ -0,0 +1,214 @@ +base_url = trailingslashit($base_url); + } + + /** + * Executes the HTTP request. + * + * @since 2.5.0 + * @param string $endpoint The request URL. + * @param array $params Query parameters. + * @param string $method HTTP method. + * @return array|WP_Error API response or WP_Error on failure. + */ + private function execute_request(string $endpoint, array $params = [], string $method = 'GET') { + + $url = $this->base_url . 'wp-json/wc/store/v1/' . ltrim($endpoint, '/'); + + if ('GET' === $method) { + $url = add_query_arg($params, $url); + $args = [ + 'method' => 'GET', + 'timeout' => 30, + ]; + } else { + $args = [ + 'method' => $method, + 'body' => wp_json_encode($params), + 'headers' => [ + 'Content-Type' => 'application/json', + ], + 'timeout' => 30, + ]; + } + + // Add authorization if available + $addon_repo = \WP_Ultimo::get_instance()->get_addon_repository(); + + $access_token = $addon_repo->get_access_token(); + if ($access_token) { + $args['headers']['Authorization'] = 'Bearer ' . $access_token; + } + + $response = wp_remote_request($url, $args); + + if (is_wp_error($response)) { + return $response; + } + + $response_code = wp_remote_retrieve_response_code($response); + $response_body = wp_remote_retrieve_body($response); + + if ($response_code < 200 || $response_code >= 300) { + return new WP_Error( + 'template_api_error', + sprintf( + /* translators: %1$s: HTTP response code, %2$s: response body */ + __('Template API request failed with status %1$s: %2$s', 'ultimate-multisite'), + $response_code, + $response_body + ) + ); + } + + $data = json_decode($response_body, true); + + if (null === $data) { + return new WP_Error( + 'json_decode_error', + __('Failed to decode API response JSON', 'ultimate-multisite') + ); + } + + return $data; + } + + /** + * Gets template products with specific metadata. + * + * @since 2.5.0 + * @return array|WP_Error Array of template products or WP_Error on failure. + */ + public function get_templates() { + + $params = [ + 'per_page' => 100, + 'status' => 'publish', + 'downloadable' => true, + 'tag' => 'template', + ]; + + $result = $this->execute_request('products', $params); + + if (is_wp_error($result)) { + return $result; + } + + // Parse and enhance template data + return array_map([$this, 'parse_template_data'], $result); + } + + /** + * Parses and enhances template data from the API response. + * + * @since 2.5.0 + * @param array $template Raw template data from API. + * @return array Enhanced template data. + */ + private function parse_template_data(array $template): array { + + $extensions = $template['extensions']['wp-update-server-plugin'] ?? []; + + return [ + 'id' => $template['id'] ?? 0, + 'slug' => $template['slug'] ?? '', + 'name' => $template['name'] ?? '', + 'description' => $template['description'] ?? '', + 'short_description' => $template['short_description'] ?? '', + 'price_html' => $template['price_html'] ?? '', + 'permalink' => $template['permalink'] ?? '', + 'is_free' => empty($template['prices']['price'] ?? 0), + 'prices' => $template['prices'] ?? [], + 'images' => $template['images'] ?? [], + 'categories' => $template['categories'] ?? [], + + // Template-specific metadata from extensions + 'icon' => $extensions['icon'] ?? '', + 'download_url' => $extensions['download_url'] ?? '', + 'author' => $extensions['author']['display_name'] ?? 'Ultimate Multisite Team', + 'demo_url' => $extensions['demo_url'] ?? '', + 'industry_type' => $extensions['industry_type'] ?? '', + 'page_count' => (int) ($extensions['page_count'] ?? 0), + 'included_plugins' => $extensions['included_plugins'] ?? [], + 'included_themes' => $extensions['included_themes'] ?? [], + 'template_version' => $extensions['template_version'] ?? '1.0.0', + 'compatibility' => [ + 'wp_version' => $extensions['compatibility']['wp_version'] ?? '', + 'wu_version' => $extensions['compatibility']['wu_version'] ?? '', + ], + + // Internal tracking + 'installed' => false, + ]; + } + + /** + * Gets a single template by slug. + * + * @since 2.5.0 + * @param string $slug The template slug. + * @return array|WP_Error Template data or WP_Error on failure. + */ + public function get_template(string $slug) { + + $templates = $this->get_templates(); + + if (is_wp_error($templates)) { + return $templates; + } + + foreach ($templates as $template) { + if ($template['slug'] === $slug) { + return $template; + } + } + + return new WP_Error( + 'template_not_found', + sprintf( + /* translators: %s: template slug */ + __('Template "%s" not found.', 'ultimate-multisite'), + $slug + ) + ); + } +} diff --git a/inc/template-library/class-template-installer.php b/inc/template-library/class-template-installer.php new file mode 100644 index 00000000..686c9964 --- /dev/null +++ b/inc/template-library/class-template-installer.php @@ -0,0 +1,245 @@ +import_template($tmp_file, $options); + + // Clean up temp file + wp_delete_file($tmp_file); + + return $result; + } + + /** + * Adds authentication headers to the download request. + * + * @since 2.5.0 + * @param array $args HTTP request arguments. + * @param string $url Request URL. + * @return array Modified arguments. + */ + public function add_auth_headers(array $args, string $url): array { + + if (strpos($url, 'ultimatemultisite.com') !== false) { + $addon_repo = \WP_Ultimo::get_instance()->get_addon_repository(); + $access_token = $addon_repo->get_access_token(); + + if ($access_token) { + $args['headers']['Authorization'] = 'Bearer ' . $access_token; + } + } + + return $args; + } + + /** + * Imports a template ZIP file as a new template site. + * + * @since 2.5.0 + * @param string $zip_path Path to the ZIP file. + * @param array $options Import options. + * @return array|WP_Error Import result or error. + */ + private function import_template(string $zip_path, array $options) { + + $defaults = [ + 'slug' => 'template', + 'name' => __('Imported Template', 'ultimate-multisite'), + 'version' => '1.0.0', + 'delete_zip' => true, + 'as_template' => true, + ]; + + $args = wp_parse_args($options, $defaults); + + // Generate a URL for the new template site + $new_url = $this->generate_template_url($args['slug']); + + // Use the core importer + $import_result = wu_exporter_import( + $zip_path, + [ + 'new_url' => $new_url, + 'delete_zip' => $args['delete_zip'], + ], + false // Sync import for now + ); + + if (is_wp_error($import_result)) { + return $import_result; + } + + // Get the created site + $site = wu_exporter_url_to_site($new_url); + + if (! $site) { + return new WP_Error( + 'site_not_found', + __('Could not find the imported template site.', 'ultimate-multisite') + ); + } + + $site_id = $site->blog_id; + + // Mark site as template + $wu_site = wu_get_site($site_id); + if ($wu_site) { + $wu_site->set_type('site_template'); + $wu_site->save(); + } + + // Record the installation + $this->record_installation( + $args['slug'], + $args['version'], + $site_id, + $new_url + ); + + return [ + 'success' => true, + 'site_id' => $site_id, + 'site_url' => $new_url, + 'message' => __('Template installed successfully!', 'ultimate-multisite'), + ]; + } + + /** + * Generates a unique URL for a template site. + * + * @since 2.5.0 + * @param string $slug The template slug. + * @return string The generated URL. + */ + private function generate_template_url(string $slug): string { + + $network_url = network_home_url(); + $path = sanitize_title('template-' . $slug . '-' . time()); + + return trailingslashit($network_url) . $path . '/'; + } + + /** + * Records a template installation. + * + * @since 2.5.0 + * @param string $template_slug Template slug. + * @param string $version Template version. + * @param int $site_id Site ID. + * @param string $site_url Site URL. + * @return bool + */ + public function record_installation(string $template_slug, string $version, int $site_id, string $site_url): bool { + + $installed_templates = $this->get_installed_templates(); + + $installed_templates[ $template_slug ] = [ + 'version' => $version, + 'installed_at' => current_time('mysql'), + 'site_id' => $site_id, + 'site_url' => $site_url, + ]; + + return wu_save_option('installed_templates', $installed_templates); + } + + /** + * Gets list of installed templates. + * + * @since 2.5.0 + * @return array + */ + public function get_installed_templates(): array { + + return wu_get_option('installed_templates', []); + } + + /** + * Checks if a template is installed. + * + * @since 2.5.0 + * @param string $template_slug Template slug. + * @return bool + */ + public function is_installed(string $template_slug): bool { + + $installed = $this->get_installed_templates(); + + return isset($installed[ $template_slug ]); + } + + /** + * Gets installed template info. + * + * @since 2.5.0 + * @param string $template_slug Template slug. + * @return array|null + */ + public function get_installed_template(string $template_slug): ?array { + + $installed = $this->get_installed_templates(); + + return $installed[ $template_slug ] ?? null; + } +} diff --git a/inc/template-library/class-template-library.php b/inc/template-library/class-template-library.php new file mode 100644 index 00000000..2f7e6756 --- /dev/null +++ b/inc/template-library/class-template-library.php @@ -0,0 +1,142 @@ +repository = new Template_Repository(); + + /** + * Fires when the Template Library is loaded. + * + * @since 2.5.0 + */ + do_action('wu_template_library_loaded'); + } + + /** + * Gets the Template Repository instance. + * + * @since 2.5.0 + * @return Template_Repository + */ + public function get_repository(): Template_Repository { + + return $this->repository; + } + + /** + * Gets templates from the repository. + * + * @since 2.5.0 + * @param bool $force_refresh Force refresh from API. + * @return array|\WP_Error + */ + public function get_templates(bool $force_refresh = false) { + + return $this->repository->get_templates($force_refresh); + } + + /** + * Gets a single template by slug. + * + * @since 2.5.0 + * @param string $slug Template slug. + * @return array|\WP_Error + */ + public function get_template(string $slug) { + + return $this->repository->get_template($slug); + } + + /** + * Installs a template. + * + * @since 2.5.0 + * @param string $slug Template slug. + * @param array $options Installation options. + * @return array|\WP_Error Installation result or error. + */ + public function install_template(string $slug, array $options = []) { + + $template = $this->get_template($slug); + + if (is_wp_error($template)) { + return $template; + } + + if (empty($template['download_url'])) { + return new \WP_Error( + 'no_download_url', + __('No download URL available for this template.', 'ultimate-multisite') + ); + } + + // Merge template info into options + $options = array_merge( + [ + 'slug' => $template['slug'], + 'name' => $template['name'], + 'version' => $template['template_version'], + ], + $options + ); + + return $this->repository->get_installer()->install($template['download_url'], $options); + } + + /** + * Checks if a template is installed. + * + * @since 2.5.0 + * @param string $slug Template slug. + * @return bool + */ + public function is_template_installed(string $slug): bool { + + return $this->repository->get_installer()->is_installed($slug); + } + + /** + * Clears the template cache. + * + * @since 2.5.0 + * @return bool + */ + public function clear_cache(): bool { + + return $this->repository->clear_cache(); + } +} diff --git a/inc/template-library/class-template-repository.php b/inc/template-library/class-template-repository.php new file mode 100644 index 00000000..95219125 --- /dev/null +++ b/inc/template-library/class-template-repository.php @@ -0,0 +1,317 @@ +api_client = new API_Client(MULTISITE_ULTIMATE_UPDATE_URL); + $this->installer = new Template_Installer(); + } + + /** + * Gets templates with caching. + * + * @since 2.5.0 + * @param bool $force_refresh Force refresh from API. + * @return array|WP_Error Array of templates or WP_Error. + */ + public function get_templates(bool $force_refresh = false) { + + // Return in-memory cache if available + if (! $force_refresh && null !== $this->templates) { + return $this->templates; + } + + // Try to get from transient cache + if (! $force_refresh && ! wu_is_debug()) { + $cached = get_site_transient(self::CACHE_KEY); + if (false !== $cached) { + $this->templates = $this->mark_installed_templates($cached); + return $this->templates; + } + } + + // Fetch from API + $templates = $this->api_client->get_templates(); + + if (is_wp_error($templates)) { + return $templates; + } + + // Cache the result + set_site_transient(self::CACHE_KEY, $templates, self::CACHE_DURATION); + + // Mark installed templates and store in memory + $this->templates = $this->mark_installed_templates($templates); + + return $this->templates; + } + + /** + * Marks templates that are already installed. + * + * @since 2.5.0 + * @param array $templates Array of templates. + * @return array Templates with installed flag. + */ + private function mark_installed_templates(array $templates): array { + + $installed = $this->installer->get_installed_templates(); + + return array_map( + function ($template) use ($installed) { + $template['installed'] = isset($installed[ $template['slug'] ]); + + // Add installed info if available + if ($template['installed']) { + $template['installed_info'] = $installed[ $template['slug'] ]; + } + + return $template; + }, + $templates + ); + } + + /** + * Gets a single template by slug. + * + * @since 2.5.0 + * @param string $slug Template slug. + * @return array|WP_Error Template data or error. + */ + public function get_template(string $slug) { + + $templates = $this->get_templates(); + + if (is_wp_error($templates)) { + return $templates; + } + + foreach ($templates as $template) { + if ($template['slug'] === $slug) { + return $template; + } + } + + return new WP_Error( + 'template_not_found', + sprintf( + /* translators: %s: template slug */ + __('Template "%s" not found.', 'ultimate-multisite'), + $slug + ) + ); + } + + /** + * Gets templates filtered by category. + * + * @since 2.5.0 + * @param string $category Category slug. + * @return array|WP_Error Filtered templates or error. + */ + public function get_templates_by_category(string $category) { + + $templates = $this->get_templates(); + + if (is_wp_error($templates)) { + return $templates; + } + + if ('all' === $category) { + return $templates; + } + + return array_filter( + $templates, + function ($template) use ($category) { + foreach ($template['categories'] as $cat) { + if ($cat['slug'] === $category) { + return true; + } + } + return false; + } + ); + } + + /** + * Searches templates by keyword. + * + * @since 2.5.0 + * @param string $search Search keyword. + * @return array|WP_Error Matching templates or error. + */ + public function search_templates(string $search) { + + $templates = $this->get_templates(); + + if (is_wp_error($templates)) { + return $templates; + } + + $search = strtolower($search); + + return array_filter( + $templates, + function ($template) use ($search) { + // Search in name + if (stripos($template['name'], $search) !== false) { + return true; + } + + // Search in description + if (stripos($template['description'], $search) !== false) { + return true; + } + + // Search in slug + if (stripos($template['slug'], $search) !== false) { + return true; + } + + // Search in industry type + if (stripos($template['industry_type'], $search) !== false) { + return true; + } + + // Search in categories + foreach ($template['categories'] as $cat) { + if (stripos($cat['name'], $search) !== false) { + return true; + } + } + + return false; + } + ); + } + + /** + * Gets all unique categories from templates. + * + * @since 2.5.0 + * @return array|WP_Error Categories or error. + */ + public function get_categories() { + + $templates = $this->get_templates(); + + if (is_wp_error($templates)) { + return $templates; + } + + $categories = []; + + foreach ($templates as $template) { + foreach ($template['categories'] as $category) { + $slug = $category['slug']; + if (! isset($categories[ $slug ])) { + $categories[ $slug ] = $category; + } + } + } + + return array_values($categories); + } + + /** + * Clears the template cache. + * + * @since 2.5.0 + * @return bool + */ + public function clear_cache(): bool { + + $this->templates = null; + return delete_site_transient(self::CACHE_KEY); + } + + /** + * Gets the installer instance. + * + * @since 2.5.0 + * @return Template_Installer + */ + public function get_installer(): Template_Installer { + + return $this->installer; + } + + /** + * Gets the API client instance. + * + * @since 2.5.0 + * @return API_Client + */ + public function get_api_client(): API_Client { + + return $this->api_client; + } +} diff --git a/phpstan.neon.dist b/phpstan.neon.dist index ff17651b..d8365ed0 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -10,6 +10,8 @@ parameters: - ./views - ./inc - ./ultimate-multisite.php + excludePaths: + - ./inc/site-exporter/mu-migration/ ignoreErrors: - message: '#Variable \$.* might not be defined.#' diff --git a/tests/WP_Ultimo/Helpers/Hash_Test.php b/tests/WP_Ultimo/Helpers/Hash_Test.php index c525c133..edeebe43 100644 --- a/tests/WP_Ultimo/Helpers/Hash_Test.php +++ b/tests/WP_Ultimo/Helpers/Hash_Test.php @@ -118,7 +118,7 @@ public function test_default_group_encoding() { $id = 555; $hash1 = Hash::encode($id); - $hash2 = Hash::encode($id, 'wp-ultimo'); + $hash2 = Hash::encode($id, 'ultimate-multisite'); $this->assertEquals($hash1, $hash2); } diff --git a/tests/WP_Ultimo/Helpers/Unique_Customer_Email_Test.php b/tests/WP_Ultimo/Helpers/Unique_Customer_Email_Test.php new file mode 100644 index 00000000..d836753f --- /dev/null +++ b/tests/WP_Ultimo/Helpers/Unique_Customer_Email_Test.php @@ -0,0 +1,146 @@ +assertTrue($rule->check('')); + $this->assertTrue($rule->check(null)); + } + + /** + * Test that a new email (no user or customer exists) passes validation. + * + * @since 2.3.0 + */ + public function test_new_email_passes() { + + $rule = new Unique_Customer_Email(); + + // Use a random email that doesn't exist + $this->assertTrue($rule->check('nonexistent-' . wp_generate_uuid4() . '@example.com')); + } + + /** + * Test that an email belonging to a WordPress user but not a customer passes validation. + * + * @since 2.3.0 + */ + public function test_email_with_user_but_no_customer_passes() { + + // Create a WordPress user without a customer using a unique email + $email = 'user-only-' . wp_generate_uuid4() . '@example.com'; + $user_id = $this->factory()->user->create([ + 'user_email' => $email, + ]); + + $user = get_user_by('id', $user_id); + $this->assertEquals($email, $user->user_email, 'User email should match created email'); + + // Delete any existing customer linked to this user (cleanup from previous test runs) + $existing_customer = wu_get_customer_by_user_id($user_id); + if ($existing_customer) { + $existing_customer->delete(); + } + + // Verify no customer is linked to this user now + $customer = wu_get_customer_by_user_id($user_id); + $this->assertFalse($customer, 'No customer should be linked to this user'); + + $rule = new Unique_Customer_Email(); + + // Should pass because no customer is linked to this user + $this->assertTrue($rule->check($user->user_email)); + } + + /** + * Test that an email belonging to an existing customer fails validation. + * + * @since 2.3.0 + */ + public function test_email_with_existing_customer_fails() { + + $email = 'customer-' . wp_generate_uuid4() . '@example.com'; + + // Create a customer using wu_create_customer + $customer = wu_create_customer([ + 'email' => $email, + 'username' => 'testcustomer' . wp_generate_password(8, false), + 'password' => 'password123', + ]); + + $this->assertInstanceOf(\WP_Ultimo\Models\Customer::class, $customer); + + $user = $customer->get_user(); + $this->assertInstanceOf(\WP_User::class, $user); + + $rule = new Unique_Customer_Email(); + + // Should fail because a customer exists with this email + $this->assertFalse($rule->check($user->user_email)); + } + + /** + * Test that the validation rule works with the Validator class. + * + * @since 2.3.0 + */ + public function test_validation_rule_works_with_validator() { + + $validator = new \WP_Ultimo\Helpers\Validator(); + + // Test with non-existent email (should pass) + $data = [ + 'email' => 'new-email-' . wp_generate_uuid4() . '@example.com', + ]; + + $rules = [ + 'email' => 'unique_customer_email', + ]; + + $result = $validator->validate($data, $rules); + $this->assertFalse($result->fails(), 'Validation should pass for new email'); + + $email = 'existing-customer-' . wp_generate_uuid4() . '@example.com'; + + // Create a customer + $customer = wu_create_customer([ + 'email' => $email, + 'username' => 'validatorcust' . wp_generate_password(8, false), + 'password' => 'password123', + ]); + + $user = $customer->get_user(); + + // Test with existing customer email (should fail) + $data = [ + 'email' => $user->user_email, + ]; + + $result = $validator->validate($data, $rules); + $this->assertTrue($result->fails(), 'Validation should fail for existing customer email'); + } +} diff --git a/views/template-library/details.php b/views/template-library/details.php new file mode 100644 index 00000000..ff989ae7 --- /dev/null +++ b/views/template-library/details.php @@ -0,0 +1,216 @@ + + +
    + +
    + +
    images[0]['thumbnail'])) : + ?> +style="background-image:url(images[0]['thumbnail']); ?>);background-position:center;"> +
    +

    name); ?>

    +
    + +
    + + + + + + + +
    + +
    + +
    + +
      +
    • + + author ?? 'Ultimate Multisite Team'); ?> +
    • + + template_version)) : ?> +
    • + + template_version); ?> +
    • + + + industry_type)) : ?> +
    • + + industry_type); ?> +
    • + + + page_count)) : ?> +
    • + + page_count); ?> +
    • + + + included_plugins) && is_array($template->included_plugins)) : ?> +
    • + +
        + included_plugins as $plugin) : ?> +
      • + + + +
      • + +
      +
    • + + + included_themes) && is_array($template->included_themes)) : ?> +
    • + + included_themes[0] ?? []; + echo esc_html(is_array($theme) ? ($theme['name'] ?? '') : $theme); + ?> +
    • + + + compatibility['wu_version'])) : ?> +
    • + + compatibility['wu_version'])); + ?> +
    • + + + compatibility['wp_version'])) : ?> +
    • + + compatibility['wp_version'])); + ?> +
    • + + + demo_url)) : ?> +
    • + + + +
    • + + + permalink)) : ?> +
    • + + + +
    • + + +
    +
    +
    + + +
    + + description); ?> + +
    + +
    + +
    + +
    + + + +
    diff --git a/views/template-library/template-library.php b/views/template-library/template-library.php new file mode 100644 index 00000000..6d582e97 --- /dev/null +++ b/views/template-library/template-library.php @@ -0,0 +1,284 @@ + + +
    + +

    + + get_title()); ?> + + get_title_links() as $action_link) : + $action_classes = isset($action_link['classes']) ? $action_link['classes'] : ''; + + ?> + + + + + + +   + + + + + + + + + + + + +

    + + + +
    +

    +
    + + + +
    + +

    +
    + +
    +

    +
    +
      +
    • + +
    • +
    +
    +
    + + +
    + +
    +
    + + 0 + +
    + +
    + $section) : ?> + + + + + +
    + +
    + +
    +
    + +
    + +
    +
    + + + + + +
    +
    + +
    +
    + +
    + +
    + +
    + + +
    + +
    + + +
    + v{{ template.template_version }} +
    + + +
    + {{ template.industry_type }} +
    +
    + +
    + +

    {{ template.name }}

    +

    + {{ template.author }} +

    + + +
    + + +
    + + + {{ template.page_count }} + + + + {{ template.included_plugins.length }} + + + + {{ template.included_themes[0].name || template.included_themes[0] }} + +
    +
    + + +
    +
    +
    + + + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    + +
    +
    +
    + +
    +

    +

    +
    +
    + +
    + + + +
    diff --git a/views/wizards/host-integrations/ready.php b/views/wizards/host-integrations/ready.php index a01e91c1..b27aad10 100644 --- a/views/wizards/host-integrations/ready.php +++ b/views/wizards/host-integrations/ready.php @@ -26,7 +26,7 @@ - +
    ' . esc_html($blog->blogname) . '' . __('Visit Dashboard') . ' | ' . - '' . __('View Site') . '' . __('Visit Dashboard', 'ultimate-multisite') . ' | ' . + '' . __('View Site', 'ultimate-multisite') . '