public function prepare_activateTwoPlugins()
 {
     $plugin1Path = PathUtils::getRelativePath(self::$testConfig->testSite->path, self::$pluginInfo['zipfile']);
     $plugin2Path = PathUtils::getRelativePath(self::$testConfig->testSite->path, self::$secondPluginInfo['zipfile']);
     self::$wpAutomation->runWpCliCommand('plugin', 'install', [$plugin1Path, $plugin2Path]);
     $this->url(self::$wpAdminPath . "/plugins.php");
 }
 /**
  * @test
  */
 public function vpconfigDoesntAllowDirectAccess()
 {
     $pluginsDir = self::$wpAutomation->getPluginsDir();
     $relativePathToPluginsDir = PathUtils::getRelativePath(self::$wpAutomation->getWebRoot(), $pluginsDir);
     $url = self::$testConfig->testSite->url . '/' . $relativePathToPluginsDir . "/versionpress/vpconfig.yml";
     $statusCode = HttpStatusCodeUtil::getStatusCode($url);
     $this->assertTrue($statusCode === 403 || $statusCode === 404, "Wrong HTTP status code ({$statusCode})");
 }
 public function __construct($name = null, array $data = [], $dataName = '')
 {
     parent::__construct($name, $data, $dataName);
     $this->staticInitialization();
     $this->gitRepository = new GitRepository(self::$testConfig->testSite->path);
     self::$wpAutomation = new WpAutomation(self::$testConfig->testSite, self::$testConfig->wpCliVersion);
     $vpdbDir = self::$wpAutomation->getVpdbDir();
     $relativePathToVpdb = PathUtils::getRelativePath(self::$testConfig->testSite->path, $vpdbDir);
     $uploadsDir = self::$wpAutomation->getUploadsDir();
     $relativePathToUploads = PathUtils::getRelativePath(self::$testConfig->testSite->path, $uploadsDir);
     $dbSchema = new DbSchemaInfo([self::$wpAutomation->getPluginsDir() . '/versionpress/.versionpress/schema.yml'], self::$testConfig->testSite->dbTablePrefix, PHP_INT_MAX);
     $actionsInfoProvider = new ActionsInfoProvider([self::$wpAutomation->getPluginsDir() . '/versionpress/.versionpress/actions.yml']);
     $this->commitAsserter = new CommitAsserter($this->gitRepository, $dbSchema, $actionsInfoProvider, ['vpdb' => $relativePathToVpdb, 'uploads' => $relativePathToUploads]);
 }
 /**
  * @test
  * @dataProvider specialPathsProvider
  */
 public function specialPaths($from, $to, $expected)
 {
     $relativePath = PathUtils::getRelativePath($from, $to);
     $this->assertEquals($expected, $relativePath, "Wrong relative path from: '{$from}' to: '{$to}'.");
 }
示例#5
0
 /**
  * Returns relative path of given path to the WP site.
  *
  * @param $absolutePath
  * @return string
  */
 protected function getRelativePath($absolutePath)
 {
     return PathUtils::getRelativePath($this->testConfig->testSite->path, $absolutePath);
 }
 /**
  * Uninstalls a merge driver - removes 'vp-ini' sections from both .gitattributes
  * and .git/config.
  *
  * @param string $rootDir
  * @param string $pluginDir
  * @param string $vpdbDir
  */
 public static function uninstallMergeDriver($rootDir, $pluginDir, $vpdbDir)
 {
     $gitconfigPath = $rootDir . '/.git/config';
     $gitattributesPath = $rootDir . '/.gitattributes';
     $gitattributesContents = file_get_contents($pluginDir . '/src/Initialization/.gitattributes.tpl');
     $gitattributesVariables = ['vpdb-dir' => PathUtils::getRelativePath($rootDir, $vpdbDir)];
     $gitattributesContents = StringUtils::fillTemplateString($gitattributesVariables, $gitattributesContents);
     if (file_exists($gitattributesPath)) {
         $gitAttributes = file_get_contents($gitattributesPath);
         $gitAttributes = str_replace($gitattributesContents, '', $gitAttributes);
         if (trim($gitAttributes) === '') {
             unlink($gitattributesPath);
         } else {
             file_put_contents($gitattributesPath, $gitAttributes);
         }
     }
     if (file_exists($gitconfigPath)) {
         $gitConfig = file_get_contents($gitconfigPath);
         // https://regex101.com/r/eJ4rJ5/4
         $mergeDriverRegex = "/(\\[merge \\\"vp\\-ini\\\"\\]\\r?\\n)([^\\[]*)/";
         $gitConfig = preg_replace($mergeDriverRegex, '', $gitConfig, 1);
         file_put_contents($gitconfigPath, $gitConfig);
     }
 }
示例#7
0
 /**
  * Installs Gitignore to the repository root, or does nothing if the file already exists.
  */
 private function installGitignore()
 {
     $gitignorePath = VP_PROJECT_ROOT . '/.gitignore';
     $projectRoot = realpath(VP_PROJECT_ROOT);
     $vpGitignore = file_get_contents(__DIR__ . '/.gitignore.tpl');
     $gitIgnoreVariables = ['wp-content' => rtrim('/' . PathUtils::getRelativePath($projectRoot, realpath(WP_CONTENT_DIR)), '/'), 'wp-plugins' => rtrim('/' . PathUtils::getRelativePath($projectRoot, realpath(WP_PLUGIN_DIR)), '/'), 'abspath' => rtrim('/' . PathUtils::getRelativePath($projectRoot, realpath(ABSPATH)), '/'), 'abspath-parent' => rtrim('/' . PathUtils::getRelativePath($projectRoot, realpath(dirname(ABSPATH))), '/')];
     $vpGitignore = StringUtils::fillTemplateString($gitIgnoreVariables, $vpGitignore);
     if (is_file($gitignorePath)) {
         $currentGitignore = file_get_contents($gitignorePath);
         if (strpos($currentGitignore, $vpGitignore) !== false) {
             return;
         }
         file_put_contents($gitignorePath, "\n" . $vpGitignore, FILE_APPEND);
     } else {
         file_put_contents($gitignorePath, $vpGitignore);
     }
 }
示例#8
0
 /**
  * Clones site to a new folder and database.
  *
  * ## OPTIONS
  *
  * --name=<name>
  * : Name of the clone. Used as a directory name, part of the DB prefix
  * and an argument to the pull & push commands later.
  *
  * [--siteurl=<url>]
  * : URL of the clone. By default, the original URL is searched for <cwd>
  * and replaced with the clone name.
  *
  * [--dbname=<dbname>]
  * : Database name for the clone.
  *
  * [--dbuser=<dbuser>]
  * : Database user for the clone.
  *
  * [--dbpass=<dbpass>]
  * : Database user password for the clone.
  *
  * [--dbhost=<dbhost>]
  * : Database host for the clone.
  *
  * [--dbprefix=<dbprefix>]
  * : Database table prefix for the clone.
  *
  * [--dbcharset=<dbcharset>]
  * : Database charset for the clone.
  *
  * [--dbcollate=<dbcollate>]
  * : Database collation for the clone.
  *
  * [--force]
  * : Forces cloning even if the target directory or DB tables exists.
  * Basically provides --yes to all warnings / confirmations.
  *
  * [--yes]
  * : Another way to force the clone
  *
  * ## EXAMPLES
  *
  * The main site lives in a directory 'wpsite', uses the 'wp_' database table prefix and is
  * accessible via 'http://localhost/wpsite'. The command
  *
  *     wp vp clone --name=myclone
  *
  * does the following:
  *
  *    - Creates new directory 'myclone' next to the current one
  *    - Clones the files there
  *    - Creates new database tables prefixed with 'wp_myclone_'
  *    - Populates database tables with data
  *    - Makes the site accessible as 'http://localhost/myclone'
  *
  *
  * @subcommand clone
  *
  */
 public function cloneSite($args = [], $assoc_args = [])
 {
     global $table_prefix;
     if (isset($assoc_args['force'])) {
         $assoc_args['yes'] = 1;
     }
     if (!VersionPress::isActive()) {
         WP_CLI::error('This site is not tracked by VersionPress. Please run "wp vp activate" before cloning.');
     }
     $name = $assoc_args['name'];
     if (!WorkflowUtils::isCloneNameValid($name)) {
         // @codingStandardsIgnoreLine
         WP_CLI::error("Clone name '{$name}' is not valid. It can only contain letters, numbers, hyphens and underscores.");
     }
     $currentWpPath = realpath(VP_PROJECT_ROOT);
     $cloneDirName = $name;
     $clonePath = dirname($currentWpPath) . '/' . $cloneDirName;
     $cloneVpPluginPath = $clonePath . '/' . str_replace($currentWpPath, '', realpath(VERSIONPRESS_PLUGIN_DIR));
     $cloneDbUser = isset($assoc_args['dbuser']) ? $assoc_args['dbuser'] : DB_USER;
     $cloneDbPassword = isset($assoc_args['dbpass']) ? $assoc_args['dbpass'] : DB_PASSWORD;
     $cloneDbName = isset($assoc_args['dbname']) ? $assoc_args['dbname'] : DB_NAME;
     $cloneDbHost = isset($assoc_args['dbhost']) ? $assoc_args['dbhost'] : DB_HOST;
     $cloneDbPrefix = isset($assoc_args['dbprefix']) ? $assoc_args['dbprefix'] : $table_prefix . $name . '_';
     $cloneDbCharset = isset($assoc_args['dbcharset']) ? $assoc_args['dbcharset'] : DB_CHARSET;
     $cloneDbCollate = isset($assoc_args['dbcollate']) ? $assoc_args['dbcollate'] : DB_COLLATE;
     // Checking the DB prefix, regex from wp-admin/setup-config.php
     if (isset($assoc_args['dbprefix']) && preg_match('|[^a-z0-9_]|i', $cloneDbPrefix)) {
         // @codingStandardsIgnoreLine
         WP_CLI::error("Table prefix '{$cloneDbPrefix}' is not valid. It can only contain letters, numbers and underscores. Please choose different one.");
     }
     $prefixChanged = false;
     if (Strings::contains($cloneDbPrefix, '-')) {
         $cloneDbPrefix = str_replace('-', '_', $cloneDbPrefix);
         $prefixChanged = true;
     }
     $currentUrl = get_home_url();
     $suggestedUrl = $this->suggestCloneUrl($currentUrl, basename($currentWpPath), $cloneDirName);
     if (!$suggestedUrl && !isset($assoc_args['siteurl'])) {
         WP_CLI::error("The command cannot derive default clone URL. Please specify the --siteurl parameter.");
     }
     $cloneUrl = isset($assoc_args['siteurl']) ? $assoc_args['siteurl'] : $suggestedUrl;
     $urlChanged = !isset($assoc_args['siteurl']) && !Strings::contains($cloneUrl, $cloneDirName);
     if (is_dir($clonePath)) {
         // @codingStandardsIgnoreLine
         WP_CLI::confirm("Directory '" . basename($clonePath) . "' already exists, it will be deleted before cloning. Proceed?", $assoc_args);
     }
     if ($this->someWpTablesExist($cloneDbUser, $cloneDbPassword, $cloneDbName, $cloneDbHost, $cloneDbPrefix)) {
         // @codingStandardsIgnoreLine
         WP_CLI::confirm("Database tables for the clone already exist, they will be dropped and re-created. Proceed?", $assoc_args);
     }
     if (is_dir($clonePath)) {
         try {
             FileSystem::removeContent($clonePath);
         } catch (IOException $e) {
             WP_CLI::error("Could not delete directory '" . basename($clonePath) . "'. Please do it manually.");
         }
     }
     vp_commit_all_frequently_written_entities();
     // Clone the site
     $cloneCommand = sprintf("git clone %s %s", ProcessUtils::escapeshellarg($currentWpPath), ProcessUtils::escapeshellarg($clonePath));
     $process = VPCommandUtils::exec($cloneCommand, $currentWpPath);
     if (!$process->isSuccessful()) {
         WP_CLI::error($process->getConsoleOutput(), false);
         WP_CLI::error("Cloning Git repo failed");
     } else {
         WP_CLI::success("Site files cloned");
     }
     // Adding the clone as a remote for the convenience of the `vp pull` command - its `--from`
     // parameter can then be just the name of the clone, not a path to it
     $addRemoteCommand = sprintf("git remote add %s %s", ProcessUtils::escapeshellarg($name), ProcessUtils::escapeshellarg($clonePath));
     $process = VPCommandUtils::exec($addRemoteCommand, $currentWpPath);
     if (!$process->isSuccessful()) {
         // @codingStandardsIgnoreLine
         $overwriteRemote = VPCommandUtils::cliQuestion("The Git repo of this site already defines remote '{$name}', overwrite it?", ["y", "n"], $assoc_args);
         if ($overwriteRemote == "y") {
             $addRemoteCommand = str_replace(" add ", " set-url ", $addRemoteCommand);
             $process = VPCommandUtils::exec($addRemoteCommand, $currentWpPath);
             if (!$process->isSuccessful()) {
                 WP_CLI::error("Could not update remote's URL");
             } else {
                 WP_CLI::success("Updated remote configuration");
             }
         }
     } else {
         WP_CLI::success("Clone added as a remote");
     }
     // Enable pushing to origin
     $configCommand = "git config receive.denyCurrentBranch ignore";
     $process = VPCommandUtils::exec($configCommand);
     if ($process->isSuccessful()) {
         WP_CLI::success("Enabled pushing to the original repository");
     } else {
         WP_CLI::error("Cannot enable pushing to the original repository");
     }
     // Enable pushing to clone
     $configCommand = "git config receive.denyCurrentBranch ignore";
     $process = VPCommandUtils::exec($configCommand, $clonePath);
     if ($process->isSuccessful()) {
         WP_CLI::success("Enabled pushing to the clone");
     } else {
         WP_CLI::error("Cannot enable pushing to the clone");
     }
     // Copy & Update wp-config
     $wpConfigFile = \WP_CLI\Utils\locate_wp_config();
     $cloneConfigFile = str_replace($currentWpPath, $clonePath, $wpConfigFile);
     copy($wpConfigFile, $cloneConfigFile);
     $this->updateConfig($clonePath, $name, $cloneDbUser, $cloneDbPassword, $cloneDbName, $cloneDbHost, $cloneDbPrefix, $cloneDbCharset, $cloneDbCollate);
     // Copy VersionPress
     FileSystem::copyDir(VERSIONPRESS_PLUGIN_DIR, $cloneVpPluginPath);
     WP_CLI::success("Copied VersionPress");
     // Finish the process by doing the standard restore-site
     $relativePathToThisFile = PathUtils::getRelativePath($currentWpPath, __FILE__);
     $process = VPCommandUtils::runWpCliCommand('vp', 'restore-site', ['siteurl' => $cloneUrl, 'yes' => null, 'require' => $relativePathToThisFile], $clonePath);
     WP_CLI::log(trim($process->getConsoleOutput()));
     if ($process->isSuccessful()) {
         WP_CLI::success("All done. Clone created here:");
         WP_CLI::log("");
         WP_CLI::log("Path:   {$clonePath}");
         WP_CLI::log("URL:    {$cloneUrl}");
         if ($urlChanged) {
             WP_CLI::log("Note: Underscores changed to hyphens for URL.");
         }
         if ($prefixChanged) {
             WP_CLI::log("Note: Hyphens changed to underscores for DB prefix.");
         }
     }
 }
 public function prepare_setFeaturedImageForUnsavedPost()
 {
     $this->url($this->getPostTypeScreenUrl());
     $addNewSelector = $this->isWpVersionLowerThan('4.3-alpha1') ? '.edit-php #wpbody-content .wrap a.add-new-h2' : '.edit-php #wpbody-content .wrap a.page-title-action';
     $this->byCssSelector($addNewSelector)->click();
     $this->waitAfterRedirect();
     $attachments = json_decode(self::$wpAutomation->runWpCliCommand('post', 'list', ['post_type' => 'attachment', 'format' => 'json']));
     if (count($attachments) > 0) {
         return;
     }
     $imagePath = PathUtils::getRelativePath(self::$testConfig->testSite->path, __DIR__ . '/../test-data/test.png');
     self::$wpAutomation->importMedia($imagePath);
 }