Пример #1
0
 /**
  * Restores a WP site from Git repo / working directory.
  *
  * ## OPTIONS
  *
  * --siteurl=<url>
  * : The address of the restored site. Default: 'http://localhost/<cwd>'
  *
  * --dbname=<dbname>
  * : Set the database name.
  *
  * --dbuser=<dbuser>
  * : Set the database user.
  *
  * --dbpass=<dbpass>
  * : Set the database user password.
  *
  * --dbhost=<dbhost>
  * : Set the database host. Default: 'localhost'
  *
  * --dbprefix=<dbprefix>
  * : Set the database table prefix. Default: 'wp_'
  *
  * --dbcharset=<dbcharset>
  * : Set the database charset. Default: 'utf8'
  *
  * --dbcollate=<dbcollate>
  * : Set the database collation. Default: ''
  *
  * --yes
  * : Answer yes to the confirmation message.
  *
  * ## DESCRIPTION
  *
  * The simplest possible example just executes `site-restore` without any parameters.
  * The assumptions are:
  *
  *    * The current directory must be reachable from the webserver as http://localhost/<cwd>
  *    * Credentials for the MySQL server are in the wp-config.php
  *
  * The command will then do the following:
  *
  *    * Create a db <dirname>, e.g., 'vp01'
  *    * Optionally configure WordPress to connect to this DB
  *    * Create WordPress tables in it and preconfigure it with site_url and home options
  *    * Run VP synchronizers on the database
  *
  * All DB credentials and site URL are configurable.
  *
  * @synopsis [--siteurl=<url>] [--dbname=<dbname>] [--dbuser=<dbuser>] [--dbpass=<dbpass>] [--dbhost=<dbhost>] [--dbprefix=<dbprefix>] [--dbcharset=<dbcharset>] [--dbcollate=<dbcollate>] [--yes]
  *
  * @subcommand restore-site
  *
  * @when before_wp_load
  */
 public function restoreSite($args, $assoc_args)
 {
     // Load VersionPress' bootstrap (WP_CONTENT_DIR needs to be defined)
     if (!defined('WP_CONTENT_DIR')) {
         define('WP_CONTENT_DIR', ABSPATH . 'wp-content');
     }
     require_once __DIR__ . '/../../bootstrap.php';
     // Check if the site is installed
     $process = VPCommandUtils::runWpCliCommand('core', 'is-installed');
     if ($process->isSuccessful()) {
         WP_CLI::confirm("It looks like the site is OK. Do you really want to run the 'restore-site' command?", $assoc_args);
         $defaultUrl = trim(VPCommandUtils::runWpCliCommand('option', 'get', array('siteurl'))->getConsoleOutput());
     } else {
         $defaultUrl = 'http://localhost/' . basename(getcwd());
     }
     $url = @$assoc_args['siteurl'] ?: $defaultUrl;
     // Confirm automatically chosen site URL
     if (!isset($assoc_args['siteurl'])) {
         WP_CLI::confirm("The site URL will be set to '{$url}'. Proceed?", $assoc_args);
     }
     // Updating wp-config.php
     if (file_exists(ABSPATH . 'wp-config.php')) {
         if ($this->issetConfigOption($assoc_args)) {
             WP_CLI::error("Site settings was loaded from wp-config.php. If you want to reconfigure the site, please delete the wp-config.php file");
         }
     } else {
         $this->configSite($assoc_args);
     }
     // Create or empty database
     $this->prepareDatabase($assoc_args);
     // Disable VersionPress tracking
     if (!defined('WPINC')) {
         define('WPINC', 'wp-includes');
     }
     WpdbReplacer::restoreOriginal();
     unlink(VERSIONPRESS_ACTIVATION_FILE);
     // Create WP tables. The only important thing is site URL, all else will be rewritten later during synchronization.
     $installArgs = array('url' => $url, 'title' => 'x', 'admin_user' => 'x', 'admin_password' => 'x', 'admin_email' => '*****@*****.**');
     $process = VPCommandUtils::runWpCliCommand('core', 'install', $installArgs);
     if (!$process->isSuccessful()) {
         WP_CLI::log("Failed creating database tables");
         WP_CLI::error($process->getConsoleOutput());
     } else {
         WP_CLI::success("Database tables created");
     }
     // Restores "wp-db.php", "wp-db.php.original" and ".active"
     $resetCmd = 'git reset --hard';
     $process = VPCommandUtils::exec($resetCmd);
     if (!$process->isSuccessful()) {
         WP_CLI::log("Could not clean working directory");
         WP_CLI::error($process->getConsoleOutput());
     }
     // The next couple of the steps need to be done after the WP is fully loaded; we use `finish-init-clone` for that
     // The main reason for this is that we need properly set WP_CONTENT_DIR constant for reading from storages
     $process = VPCommandUtils::runWpCliCommand('vp-internal', 'finish-init-clone', array('require' => $this->getVPInternalCommandPath()));
     WP_CLI::log($process->getConsoleOutput());
     if (!$process->isSuccessful()) {
         WP_CLI::error("Could not finish site restore");
     }
 }
Пример #2
0
/**
 * Most of the actual deactivation work is done here. Called either as a response
 * to the user confirming the deactivation on `?page=versionpress/admin/deactivate.php`
 * or is called directly from vp_deactivate() if the confirmation screen was not necessary.
 */
function vp_admin_post_confirm_deactivation()
{
    //nonce verification is performed according to 'deactivate-plugin_versionpress/versionpress.php'
    // as a standard deactivation token for which nonce is generated
    if (!defined('WP_CLI')) {
        vp_verify_nonce('deactivate-plugin_versionpress/versionpress.php');
        vp_check_permissions();
    }
    define('VP_DEACTIVATING', true);
    if (WpdbReplacer::isReplaced()) {
        WpdbReplacer::restoreOriginal();
    }
    if (file_exists(VERSIONPRESS_ACTIVATION_FILE)) {
        FileSystem::remove(VERSIONPRESS_ACTIVATION_FILE);
    }
    $filesChangedByDeactivation = [["type" => "path", "path" => VP_VPDB_DIR . "/*"], ["type" => "path", "path" => ABSPATH . WPINC . "/wp-db.php"], ["type" => "path", "path" => ABSPATH . WPINC . "/wp-db.php.original"], ["type" => "path", "path" => ABSPATH . "/.gitattributes"]];
    vp_force_action('versionpress', 'deactivate', null, [], $filesChangedByDeactivation);
    MergeDriverInstaller::uninstallMergeDriver(VP_PROJECT_ROOT, VERSIONPRESS_PLUGIN_DIR, VP_VPDB_DIR);
    deactivate_plugins("versionpress/versionpress.php", true);
    if (defined('WP_ADMIN')) {
        wp_safe_redirect(admin_url("plugins.php"));
        exit;
    }
}
Пример #3
0
/**
 * Most of the actual deactivation work is done here. Called either as a response
 * to the user confirming the deactivation on `?page=versionpress/admin/deactivate.php`
 * or is called directly from vp_deactivate() if the confirmation screen was not necessary.
 */
function vp_admin_post_confirm_deactivation()
{
    define('VP_DEACTIVATING', true);
    if (WpdbReplacer::isReplaced()) {
        WpdbReplacer::restoreOriginal();
    }
    if (file_exists(VERSIONPRESS_ACTIVATION_FILE)) {
        FileSystem::remove(VERSIONPRESS_ACTIVATION_FILE);
    }
    FileSystem::remove(VERSIONPRESS_MIRRORING_DIR);
    global $versionPressContainer;
    /** @var Committer $committer */
    $committer = $versionPressContainer->resolve(VersionPressServices::COMMITTER);
    $committer->forceChangeInfo(new VersionPressChangeInfo("deactivate"));
    /** @var WpdbMirrorBridge $wpdbMirrorBridge */
    $wpdbMirrorBridge = $versionPressContainer->resolve(VersionPressServices::WPDB_MIRROR_BRIDGE);
    $wpdbMirrorBridge->disable();
    global $wpdb;
    $table_prefix = $wpdb->prefix;
    $queries[] = "DROP TABLE IF EXISTS `{$table_prefix}vp_id`";
    $vpOptionsReflection = new ReflectionClass('VersionPress\\Initialization\\VersionPressOptions');
    $usermetaToDelete = array_values($vpOptionsReflection->getConstants());
    $queryRestriction = '"' . join('", "', $usermetaToDelete) . '"';
    $queries[] = "DELETE FROM `{$table_prefix}usermeta` WHERE meta_key IN ({$queryRestriction})";
    foreach ($queries as $query) {
        $wpdb->query($query);
    }
    delete_option('vp_rest_api_plugin_version');
    deactivate_plugins("versionpress/versionpress.php", true);
    if (defined('WP_ADMIN')) {
        wp_redirect(admin_url("plugins.php"));
    }
}
Пример #4
0
 private function activateVersionPress()
 {
     WpdbReplacer::replaceMethods();
     touch(VERSIONPRESS_ACTIVATION_FILE);
     $this->reportProgressChange(InitializerStates::VERSIONPRESS_ACTIVATED);
 }
Пример #5
0
 /**
  * Restores a WP site from Git repo / working directory.
  *
  * ## OPTIONS
  *
  * --siteurl=<url>
  * : The address of the restored site.
  *
  * [--yes]
  * : Answer yes to the confirmation message.
  *
  * ## DESCRIPTION
  *
  * The command will then do the following:
  *
  *    * Drops all tables tracked by VersionPress.
  *    * Recreates and fill them with data from repository.
  *
  * If you just cloned the site from another repository, run `wp core config` first.
  *
  *
  * @subcommand restore-site
  *
  * @when before_wp_load
  */
 public function restoreSite($args, $assoc_args)
 {
     if (file_exists(getcwd() . '/composer.json')) {
         $proc = proc_open("composer install", [1 => ["pipe", "w"], ["pipe", "w"]], $_);
         $result = proc_close($proc);
         if ($result !== 0) {
             WP_CLI::error('Composer dependencies could not be restored.');
         }
     }
     defined('SHORTINIT') or define('SHORTINIT', true);
     require_once __DIR__ . '/../Initialization/WpConfigSplitter.php';
     $wpConfigPath = \WP_CLI\Utils\locate_wp_config();
     $this->requireWpConfig($wpConfigPath, WpConfigSplitter::COMMON_CONFIG_NAME);
     require_once __DIR__ . '/../../bootstrap.php';
     if (!VersionPress::isActive()) {
         WP_CLI::error('Unfortunately, this site was not tracked by VersionPress.
         Therefore, it cannot be restored.');
     }
     // Check if the site is installed
     $process = VPCommandUtils::runWpCliCommand('core', 'is-installed');
     if ($process->isSuccessful()) {
         $this->checkVpRequirements($assoc_args, RequirementsChecker::ENVIRONMENT);
         WP_CLI::confirm("It looks like the site is OK. Do you really want to run the 'restore-site' command?", $assoc_args);
     }
     $url = $assoc_args['siteurl'];
     // Update URLs in wp-config.php
     define('VP_INDEX_DIR', dirname(\WP_CLI\Utils\locate_wp_config()));
     // just for the following method
     $this->setConfigUrl('WP_CONTENT_URL', 'WP_CONTENT_DIR', ABSPATH . 'wp-content', $url);
     $this->setConfigUrl('WP_PLUGIN_URL', 'WP_PLUGIN_DIR', WP_CONTENT_DIR . '/plugins', $url);
     $this->setConfigUrl('WP_HOME', 'VP_INDEX_DIR', VP_PROJECT_ROOT, $url);
     defined('WP_PLUGIN_DIR') || define('WP_PLUGIN_DIR', WP_CONTENT_DIR . '/plugins');
     WpConfigSplitter::ensureCommonConfigInclude($wpConfigPath);
     // Disable VersionPress tracking for a while
     WpdbReplacer::restoreOriginal();
     unlink(VERSIONPRESS_ACTIVATION_FILE);
     // Create or empty database
     $this->prepareDatabase($assoc_args);
     // Create WP tables.
     // The only important thing is site URL, all else will be rewritten later during synchronization.
     $installArgs = ['url' => $url, 'title' => 'x', 'admin_user' => 'x', 'admin_password' => 'x', 'admin_email' => '*****@*****.**'];
     if (version_compare(WP_CLI_VERSION, '0.22.0', '>=')) {
         $installArgs['skip-email'] = null;
     }
     $process = VPCommandUtils::runWpCliCommand('core', 'install', $installArgs);
     if (!$process->isSuccessful()) {
         WP_CLI::log("Failed creating database tables");
         WP_CLI::error($process->getConsoleOutput());
     } else {
         WP_CLI::success("Database tables created");
     }
     // Restores "wp-db.php", "wp-db.php.original" and ".active" - enables VP
     $resetCmd = 'git reset --hard';
     $process = VPCommandUtils::exec($resetCmd);
     if (!$process->isSuccessful()) {
         WP_CLI::log("Could not clean working directory");
         WP_CLI::error($process->getConsoleOutput());
     }
     // Fail-safe for gitignored WordPress
     if (!WpdbReplacer::isReplaced()) {
         WpdbReplacer::replaceMethods();
     }
     /* We need correct value in the `active_plugins` option before the synchronization run.
      * Without this option VersionPress doesn't know which schema.yml files it should load and consequently which
      * DB entities it should synchronize.
      */
     $activePluginsOption = IniSerializer::deserialize(file_get_contents(VP_VPDB_DIR . '/options/ac/active_plugins.ini'));
     $activePlugins = json_encode(unserialize($activePluginsOption['active_plugins']['option_value']));
     VPCommandUtils::runWpCliCommand('option', 'update', ['active_plugins', $activePlugins, 'autoload' => 'yes', 'format' => 'json', 'skip-plugins' => null]);
     // The next couple of the steps need to be done after WP is fully loaded; we use `finish-restore-site` for that
     // The main reason for this is that we need properly set WP_CONTENT_DIR constant for reading from storages
     $process = $this->runVPInternalCommand('finish-restore-site');
     WP_CLI::log($process->getConsoleOutput());
     if (!$process->isSuccessful()) {
         WP_CLI::error("Could not finish site restore");
     }
 }
Пример #6
0
add_filter('vp_entity_files_composer', function ($files) {
    $files[] = ["type" => "path", "path" => VP_PROJECT_ROOT . '/composer.json'];
    $files[] = ["type" => "path", "path" => VP_PROJECT_ROOT . '/composer.lock'];
    return $files;
});
add_action('vp_wordpress_updated', function ($version) {
    global $versionPressContainer;
    $wpFiles = [["type" => "path", "path" => "index.php"], ["type" => "path", "path" => "license.txt"], ["type" => "path", "path" => "readme.html"], ["type" => "path", "path" => "wp-activate.php"], ["type" => "path", "path" => "wp-blog-header.php"], ["type" => "path", "path" => "wp-comments-post.php"], ["type" => "path", "path" => "wp-config-sample.php"], ["type" => "path", "path" => "wp-cron.php"], ["type" => "path", "path" => "wp-links-opml.php"], ["type" => "path", "path" => "wp-load.php"], ["type" => "path", "path" => "wp-login.php"], ["type" => "path", "path" => "wp-mail.php"], ["type" => "path", "path" => "wp-settings.php"], ["type" => "path", "path" => "wp-signup.php"], ["type" => "path", "path" => "wp-trackback.php"], ["type" => "path", "path" => "xmlrpc.php"], ["type" => "path", "path" => ABSPATH . WPINC . '/*'], ["type" => "path", "path" => ABSPATH . 'wp-admin/*'], ["type" => "path", "path" => WP_CONTENT_DIR . '/themes/twenty*'], ["type" => "path", "path" => WP_CONTENT_DIR . '/languages/*'], ["type" => "path", "path" => VP_VPDB_DIR . '/.schema/*'], ["type" => "path", "path" => VP_PROJECT_ROOT . '/composer.json'], ["type" => "path", "path" => VP_PROJECT_ROOT . '/composer.lock']];
    /** @var DbSchemaInfo $dbSchema */
    $dbSchema = $versionPressContainer->resolve(VersionPressServices::DB_SCHEMA);
    $tableSchemaStorage = $versionPressContainer->resolve(VersionPressServices::TABLE_SCHEMA_STORAGE);
    $dbSchema->refreshDbSchema(new ActivePluginsVPFilesIterator('schema.yml'));
    vp_update_table_ddl_scripts($dbSchema, $tableSchemaStorage);
    vp_force_action('wordpress', 'update', $version, [], $wpFiles);
    if (!WpdbReplacer::isReplaced()) {
        WpdbReplacer::replaceMethods();
    }
});
add_action('vp_plugin_changed', function ($action, $pluginFile, $pluginName) {
    global $versionPressContainer;
    /** @var DbSchemaInfo $dbSchema */
    $dbSchema = $versionPressContainer->resolve(VersionPressServices::DB_SCHEMA);
    $tableSchemaStorage = $versionPressContainer->resolve(VersionPressServices::TABLE_SCHEMA_STORAGE);
    $dbSchema->refreshDbSchema(new ActivePluginsVPFilesIterator('schema.yml'));
    vp_update_table_ddl_scripts($dbSchema, $tableSchemaStorage);
    if ($action !== 'delete') {
        /** @var ActionsDefinitionRepository $actionsDefinitionRepository */
        $actionsDefinitionRepository = $versionPressContainer->resolve(VersionPressServices::ACTIONS_DEFINITION_REPOSITORY);
        $actionsDefinitionRepository->saveDefinitionForPlugin($pluginFile);
    }
    $pluginPath = WP_PLUGIN_DIR . "/";