Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
'7.4'
]
suite:
- acceptance
# - acceptance # Disabled due to newer WordPress versions requirements.
- climodule
- functional
- muloader
Expand All @@ -51,7 +51,7 @@ jobs:
- wploader_multisite
- wploader_wpdb_interaction
- wploadersuite
name: v3.5 unit php@${{ matrix.php_version }}
name: v3.5 ${{ matrix.suite }} php@${{ matrix.php_version }}
runs-on: ubuntu-22.04
steps:
- name: Checkout
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ This project adheres to [Semantic Versioning](http://semver.org/).

## [unreleased] Unreleased

### Added

- The `WPLoader` module will now attempt resolving the `WP_CONTENT_DIR`, `WP_PLUGIN_DIR`, `WPMU_PLUGIN_DIR` and
`pluginsFolder` configuration parameters from the Codeception root directory if not possible to resolve them from the
current working directory. (thanks @BrianHenryIE)

### Fixed

- Restored support for the `allow-root` configuration parameter in the `WPCLI` module.
- Extensions event subscription to avoid type issues with newer PHP versions.
- Correctly serialize and unserialize options in the SQLite database implementation.
- Fix `Symlinker` extension issue where the target link path would be built incorrectly.

## [3.7.12] 2025-02-22;

### Fixed
Expand Down
8 changes: 0 additions & 8 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,3 @@ clean_procs:
rm -f var/_output/*.pid var/_output/*.running
set -o allexport && source tests/.env && set +o allexport && docker compose down
.PHONY: clean_procs

build_35:
rm -rf vendor composer.lock
composer require --dev rector/rector -W
vendor/bin/rector --config=config/rector-35.php
rm -rf vendor composer.lock composer.json
cp config/composer-35.json composer.json
.PHONY: build_35
6 changes: 5 additions & 1 deletion includes/opis/closure/src/SerializableClosure.php
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,11 @@ protected function mapPointers(&$data)
break;
}
foreach ($reflection->getProperties() as $property) {
if ($property->isStatic() || !$property->getDeclaringClass()->isUserDefined()) {
if (
$property->isStatic()
|| !$property->getDeclaringClass()->isUserDefined()
|| (method_exists($property, 'isReadOnly') && $property->isReadOnly())
) {
continue;
}
$property->setAccessible(true);
Expand Down
8 changes: 4 additions & 4 deletions src/Extension/EventDispatcherBridge.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
class EventDispatcherBridge extends Extension
{
/**
* @var array<string,string>
* @var array<string,array{0: string, 1: int}>
*/
public static $events = [
Events::MODULE_INIT => 'onModuleInit',
Events::SUITE_INIT => 'onSuiteInit',
Events::SUITE_BEFORE => 'onSuiteBefore',
Events::MODULE_INIT => ['onModuleInit', 0 ],
Events::SUITE_INIT => ['onSuiteInit', 0],
Events::SUITE_BEFORE => ['onSuiteBefore', 0],
];
/**
* @var bool
Expand Down
8 changes: 4 additions & 4 deletions src/Extension/IsolationSupport.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ class IsolationSupport extends Extension
public const ISOLATED_PROCESS_PATCH_CONTEXT = 'Isolation-Support-Process';

/**
* @var array<string,string>
* @var array<string,array{0: string, 1: int}>
*/
public static $events = [
Events::SUITE_INIT => 'onSuiteInit',
Events::TEST_START => 'onTestStart',
Events::TEST_FAIL => 'onTestFail',
Events::SUITE_INIT => ['onSuiteInit', 0],
Events::TEST_START => ['onTestStart', 0],
Events::TEST_FAIL => ['onTestFail', 0],
];

/**
Expand Down
4 changes: 2 additions & 2 deletions src/Extension/ServiceExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
abstract class ServiceExtension extends Extension
{
/**
* @var array<string,string>
* @var array<string,array{0: string, 1: int}>
*/
public static $events = [
Events::MODULE_INIT => 'onModuleInit',
Events::MODULE_INIT => ['onModuleInit', 0],
];

/**
Expand Down
10 changes: 5 additions & 5 deletions src/Extension/Symlinker.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
class Symlinker extends Extension
{
/**
* @var array<string,string>
* @var array<string,array{0: string, 1: int}>
*/
protected static $events = [
Events::MODULE_INIT => 'onModuleInit',
Events::SUITE_AFTER => 'afterSuite',
Events::MODULE_INIT => ['onModuleInit', 0],
Events::SUITE_AFTER => ['afterSuite', 0],
];

/**
Expand Down Expand Up @@ -130,7 +130,7 @@ public function onModuleInit(SuiteEvent $event): void
*/
private function symlinkPlugin(string $plugin, string $pluginsDir): void
{
$link = $pluginsDir . basename($plugin);
$link = rtrim($pluginsDir, "\\/") .DIRECTORY_SEPARATOR. ltrim(basename($plugin), "\\/");

if (is_link($link)) {
$target = readlink($link);
Expand Down Expand Up @@ -163,7 +163,7 @@ private function symlinkPlugin(string $plugin, string $pluginsDir): void
private function symlinkTheme(string $theme, string $themesDir): void
{
$target = $theme;
$link = $themesDir . basename($theme);
$link = rtrim($themesDir, "\\/") . DIRECTORY_SEPARATOR . ltrim(basename($theme), "\\/");

if (is_link($link)) {
$target = readlink($link);
Expand Down
13 changes: 7 additions & 6 deletions src/ManagedProcess/MysqlServer.php
Original file line number Diff line number Diff line change
Expand Up @@ -486,17 +486,17 @@ public function getArchiveUrl(): string

if ($operatingSystem === MachineInformation::OS_DARWIN) {
return $architecture === 'arm64' ?
'https://downloads.mysql.com/archives/get/p/23/file/mysql-8.4.3-macos14-arm64.tar.gz'
: 'https://downloads.mysql.com/archives/get/p/23/file/mysql-8.4.3-macos14-x86_64.tar.gz';
'https://dev.mysql.com/get/Downloads/MySQL-8.4/mysql-8.4.3-macos14-arm64.tar.gz'
: 'https://dev.mysql.com/get/Downloads/MySQL-8.4/mysql-8.4.3-macos14-x86_64.tar.gz';
}

if ($operatingSystem === MachineInformation::OS_LINUX) {
return $architecture === 'arm64' ?
'https://downloads.mysql.com/archives/get/p/23/file/mysql-8.4.3-linux-glibc2.17-aarch64-minimal.tar'
: 'https://downloads.mysql.com/archives/get/p/23/file/mysql-8.4.3-linux-glibc2.17-x86_64-minimal.tar';
'https://dev.mysql.com/get/Downloads/MySQL-8.4/mysql-8.4.3-linux-glibc2.17-aarch64-minimal.tar.xz'
: 'https://dev.mysql.com/get/Downloads/MySQL-8.4/mysql-8.4.3-linux-glibc2.17-x86_64-minimal.tar.xz';
}

return 'https://downloads.mysql.com/archives/get/p/23/file/mysql-8.4.3-winx64.zip';
return 'https://dev.mysql.com/get/Downloads/MySQL-8.4/mysql-8.4.3-winx64.zip';
}

public function getArchivePath(bool $normalize = false): string
Expand Down Expand Up @@ -532,7 +532,8 @@ private function extractArchiveWithPhar(string $archivePath, string $directory):
{
$memoryLimit = ini_set('memory_limit', '1G');
try {
$extracted = (new PharData($archivePath))->extractTo($directory, null, true);
$flags = \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::UNIX_PATHS;
$extracted = (new PharData($archivePath, $flags, null, 0))->extractTo($directory, null, true);
} catch (\Exception $e) {
throw new RuntimeException(
"Could not extract MySQL Server archive from $archivePath to "
Expand Down
19 changes: 16 additions & 3 deletions src/Module/WPCLI.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class WPCLI extends Module
'no-color' => true,
'debug' => true,
'quiet' => true,
'allow-root' => true,
];
/**
* @var array<string>
Expand Down Expand Up @@ -77,7 +78,8 @@ class WPCLI extends Module
* config-path?: string,
* custom-shell?: string,
* packages-dir?: string,
* bin?: string
* bin?: string,
* allow-root?: bool
* }
*/
protected $config = [
Expand Down Expand Up @@ -135,7 +137,8 @@ public function cli($command = ['core', 'version'], ?array $env = null, $input =
* config-path?: string,
* custom-shell?: string,
* packages-dir?: string,
* bin?: string
* bin?: string,
* allow-root?: bool
* } $config
*/
$config = $this->config;
Expand Down Expand Up @@ -504,7 +507,17 @@ protected function validateConfig(): void
}
}

foreach (['skip-plugins', 'skip-themes', 'skip-packages', 'debug', 'quiet', 'color', 'no-color'] as $boolKey) {
foreach ([
'skip-plugins',
'skip-themes',
'skip-packages',
'debug',
'quiet',
'color',
'no-color',
'allow-root'
] as $boolKey
) {
if (empty($this->config[$boolKey])) {
unset($this->config[$boolKey]);
} else {
Expand Down
9 changes: 9 additions & 0 deletions src/Module/WPLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,15 @@ static function ($v) {
);
}

foreach (['WP_CONTENT_DIR', 'WP_PLUGIN_DIR', 'WPMU_PLUGIN_DIR', 'pluginsFolder'] as $pathConst) {
if (!empty($this->config[$pathConst])
&& !is_dir($this->config[$pathConst])
&& is_dir(codecept_root_dir($this->config[$pathConst]))
) {
$this->config[$pathConst] = codecept_root_dir($this->config[$pathConst]);
}
}

parent::validateConfig();
}

Expand Down
3 changes: 3 additions & 0 deletions src/Process/SerializableThrowable.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public function __construct(Throwable $throwable)
$this->line = $throwable->getLine();
}

// @phpcs:disable
/**
* @return array{
* colorize: bool,
Expand Down Expand Up @@ -102,6 +103,7 @@ public function __unserialize(array $data): void
$this->line = $data['line'];
$this->trace = $data['trace'];
}
// @phpcs:enable

/**
* @throws ReflectionException
Expand Down Expand Up @@ -133,6 +135,7 @@ private function prettyPrintTrace(array $trace): array
$updatedTrace = [];
$streamIsatty = function ($stream) {
if (\function_exists('stream_isatty')) {
// @phpcs:ignore PHPCompatibility.FunctionUse.NewFunctions.stream_isattyFound
return stream_isatty($stream);
}
if (!\is_resource($stream)) {
Expand Down
7 changes: 7 additions & 0 deletions src/Utils/Download.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ public static function fileFromUrl(
curl_setopt($curlHandle, CURLOPT_TIMEOUT, 120);
curl_setopt($curlHandle, CURLOPT_FILE, $file);

// Set the user agent header.
curl_setopt(
$curlHandle,
CURLOPT_USERAGENT,
'Mozilla/5.0 (compatible; Embedded MySql; +https://github.com/lucatume/wp-browser'
);

if (!$verifyHost) {
/** @noinspection CurlSslServerSpoofingInspection */
curl_setopt($curlHandle, CURLOPT_SSL_VERIFYHOST, 0);
Expand Down
58 changes: 33 additions & 25 deletions src/Utils/MachineInformation.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,33 +24,41 @@ class MachineInformation

public function __construct(?string $operatingSystem = null, ?string $architecture = null)
{
switch (strtolower(substr(php_uname('s'), 0, 3))) {
case 'dar':
$this->operatingSystem = self::OS_DARWIN;
break;
case 'lin':
$this->operatingSystem = self::OS_LINUX;
break;
case 'win':
$this->operatingSystem = self::OS_WINDOWS;
break;
default:
$this->operatingSystem = self::OS_UNKNOWN;
break;
if ($operatingSystem === null) {
switch (strtolower(substr(php_uname('s'), 0, 3))) {
case 'dar':
$this->operatingSystem = self::OS_DARWIN;
break;
case 'lin':
$this->operatingSystem = self::OS_LINUX;
break;
case 'win':
$this->operatingSystem = self::OS_WINDOWS;
break;
default:
$this->operatingSystem = self::OS_UNKNOWN;
break;
}
} else {
$this->operatingSystem = $operatingSystem;
}

switch (strtolower(php_uname('m'))) {
case 'x86_64':
case 'amd64':
$this->architecture = self::ARCH_X86_64;
break;
case 'arm64':
case 'aarch64':
$this->architecture = self::ARCH_ARM64;
break;
default:
$this->architecture = self::ARCH_UNKNOWN;
break;
if ($architecture === null) {
switch (strtolower(php_uname('m'))) {
case 'x86_64':
case 'amd64':
$this->architecture = self::ARCH_X86_64;
break;
case 'arm64':
case 'aarch64':
$this->architecture = self::ARCH_ARM64;
break;
default:
$this->architecture = self::ARCH_UNKNOWN;
break;
}
} else {
$this->architecture = $architecture;
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/WordPress/Database/SQLiteDatabase.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace lucatume\WPBrowser\WordPress\Database;

use lucatume\WPBrowser\Utils\Serializer;
use lucatume\WPBrowser\WordPress\DbException;
use lucatume\WPBrowser\WordPress\WPConfigFile;
use PDO;
Expand Down Expand Up @@ -198,7 +199,7 @@ public function updateOption(string $name, $value): int
);
}

$stmt->execute([':name' => $name, ':value' => $value, ':autoload' => 'yes']);
$stmt->execute([':name' => $name, ':value' => Serializer::maybeSerialize($value), ':autoload' => 'yes']);
return $stmt->rowCount();
}

Expand All @@ -224,7 +225,7 @@ public function getOption(string $name, $default = null)
if ($value === false) {
return $default;
}
return $value;
return Serializer::maybeUnserialize($value);
}

public function getDbDir(): string
Expand Down
4 changes: 3 additions & 1 deletion src/WordPress/FileRequests/FileRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public function execute(): array
{
if (count($this->presetGlobalVars) > 0) {
foreach ($this->presetGlobalVars as $key => $value) {
global $$key;
global $$key; // @phpcs:ignore PHPCompatibility.Variables.ForbiddenGlobalVariableVariable.NonBareVariableFound
$$key = $value;
}
}
Expand Down Expand Up @@ -207,6 +207,7 @@ public function execute(): array
return $returnValues;
}

// @phpcs:disable
/**
* @return array{
* afterLoadClosures: array<Closure>,
Expand Down Expand Up @@ -278,6 +279,7 @@ public function __unserialize(array $data): void
throw new FileRequestException('No target file specified.');
}
}
// @phpcs:enable

public function setServerVar(string $key, string $value): FileRequest
{
Expand Down
Empty file added tests/_data/_content/.gitkeep
Empty file.
Empty file.
Empty file added tests/_data/_plugins/.gitkeep
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Loading