+ * @author Nicolas Grekas
+ *
+ * @internal
+ */
+final class Php80
+{
+ public static function fdiv(float $dividend, float $divisor): float
+ {
+ return @($dividend / $divisor);
+ }
+
+ public static function get_debug_type($value): string
+ {
+ switch (true) {
+ case null === $value: return 'null';
+ case \is_bool($value): return 'bool';
+ case \is_string($value): return 'string';
+ case \is_array($value): return 'array';
+ case \is_int($value): return 'int';
+ case \is_float($value): return 'float';
+ case \is_object($value): break;
+ case $value instanceof \__PHP_Incomplete_Class: return '__PHP_Incomplete_Class';
+ default:
+ if (null === $type = @get_resource_type($value)) {
+ return 'unknown';
+ }
+
+ if ('Unknown' === $type) {
+ $type = 'closed';
+ }
+
+ return "resource ($type)";
+ }
+
+ $class = \get_class($value);
+
+ if (false === strpos($class, '@')) {
+ return $class;
+ }
+
+ return (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous';
+ }
+
+ public static function get_resource_id($res): int
+ {
+ if (!\is_resource($res) && null === @get_resource_type($res)) {
+ throw new \TypeError(sprintf('Argument 1 passed to get_resource_id() must be of the type resource, %s given', get_debug_type($res)));
+ }
+
+ return (int) $res;
+ }
+
+ public static function preg_last_error_msg(): string
+ {
+ switch (preg_last_error()) {
+ case \PREG_INTERNAL_ERROR:
+ return 'Internal error';
+ case \PREG_BAD_UTF8_ERROR:
+ return 'Malformed UTF-8 characters, possibly incorrectly encoded';
+ case \PREG_BAD_UTF8_OFFSET_ERROR:
+ return 'The offset did not correspond to the beginning of a valid UTF-8 code point';
+ case \PREG_BACKTRACK_LIMIT_ERROR:
+ return 'Backtrack limit exhausted';
+ case \PREG_RECURSION_LIMIT_ERROR:
+ return 'Recursion limit exhausted';
+ case \PREG_JIT_STACKLIMIT_ERROR:
+ return 'JIT stack limit exhausted';
+ case \PREG_NO_ERROR:
+ return 'No error';
+ default:
+ return 'Unknown error';
+ }
+ }
+
+ public static function str_contains(string $haystack, string $needle): bool
+ {
+ return '' === $needle || false !== strpos($haystack, $needle);
+ }
+
+ public static function str_starts_with(string $haystack, string $needle): bool
+ {
+ return 0 === strncmp($haystack, $needle, \strlen($needle));
+ }
+
+ public static function str_ends_with(string $haystack, string $needle): bool
+ {
+ if ('' === $needle || $needle === $haystack) {
+ return true;
+ }
+
+ if ('' === $haystack) {
+ return false;
+ }
+
+ $needleLength = \strlen($needle);
+
+ return $needleLength <= \strlen($haystack) && 0 === substr_compare($haystack, $needle, -$needleLength);
+ }
+}
diff --git a/vendor/symfony/polyfill-php80/PhpToken.php b/vendor/symfony/polyfill-php80/PhpToken.php
new file mode 100644
index 00000000..fe6e6910
--- /dev/null
+++ b/vendor/symfony/polyfill-php80/PhpToken.php
@@ -0,0 +1,103 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Polyfill\Php80;
+
+/**
+ * @author Fedonyuk Anton
+ *
+ * @internal
+ */
+class PhpToken implements \Stringable
+{
+ /**
+ * @var int
+ */
+ public $id;
+
+ /**
+ * @var string
+ */
+ public $text;
+
+ /**
+ * @var int
+ */
+ public $line;
+
+ /**
+ * @var int
+ */
+ public $pos;
+
+ public function __construct(int $id, string $text, int $line = -1, int $position = -1)
+ {
+ $this->id = $id;
+ $this->text = $text;
+ $this->line = $line;
+ $this->pos = $position;
+ }
+
+ public function getTokenName(): ?string
+ {
+ if ('UNKNOWN' === $name = token_name($this->id)) {
+ $name = \strlen($this->text) > 1 || \ord($this->text) < 32 ? null : $this->text;
+ }
+
+ return $name;
+ }
+
+ /**
+ * @param int|string|array $kind
+ */
+ public function is($kind): bool
+ {
+ foreach ((array) $kind as $value) {
+ if (\in_array($value, [$this->id, $this->text], true)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public function isIgnorable(): bool
+ {
+ return \in_array($this->id, [\T_WHITESPACE, \T_COMMENT, \T_DOC_COMMENT, \T_OPEN_TAG], true);
+ }
+
+ public function __toString(): string
+ {
+ return (string) $this->text;
+ }
+
+ /**
+ * @return static[]
+ */
+ public static function tokenize(string $code, int $flags = 0): array
+ {
+ $line = 1;
+ $position = 0;
+ $tokens = token_get_all($code, $flags);
+ foreach ($tokens as $index => $token) {
+ if (\is_string($token)) {
+ $id = \ord($token);
+ $text = $token;
+ } else {
+ [$id, $text, $line] = $token;
+ }
+ $tokens[$index] = new static($id, $text, $line, $position);
+ $position += \strlen($text);
+ }
+
+ return $tokens;
+ }
+}
diff --git a/vendor/symfony/polyfill-php80/README.md b/vendor/symfony/polyfill-php80/README.md
new file mode 100644
index 00000000..3816c559
--- /dev/null
+++ b/vendor/symfony/polyfill-php80/README.md
@@ -0,0 +1,25 @@
+Symfony Polyfill / Php80
+========================
+
+This component provides features added to PHP 8.0 core:
+
+- [`Stringable`](https://php.net/stringable) interface
+- [`fdiv`](https://php.net/fdiv)
+- [`ValueError`](https://php.net/valueerror) class
+- [`UnhandledMatchError`](https://php.net/unhandledmatcherror) class
+- `FILTER_VALIDATE_BOOL` constant
+- [`get_debug_type`](https://php.net/get_debug_type)
+- [`PhpToken`](https://php.net/phptoken) class
+- [`preg_last_error_msg`](https://php.net/preg_last_error_msg)
+- [`str_contains`](https://php.net/str_contains)
+- [`str_starts_with`](https://php.net/str_starts_with)
+- [`str_ends_with`](https://php.net/str_ends_with)
+- [`get_resource_id`](https://php.net/get_resource_id)
+
+More information can be found in the
+[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md).
+
+License
+=======
+
+This library is released under the [MIT license](LICENSE).
diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php b/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php
new file mode 100644
index 00000000..2b955423
--- /dev/null
+++ b/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+#[Attribute(Attribute::TARGET_CLASS)]
+final class Attribute
+{
+ public const TARGET_CLASS = 1;
+ public const TARGET_FUNCTION = 2;
+ public const TARGET_METHOD = 4;
+ public const TARGET_PROPERTY = 8;
+ public const TARGET_CLASS_CONSTANT = 16;
+ public const TARGET_PARAMETER = 32;
+ public const TARGET_ALL = 63;
+ public const IS_REPEATABLE = 64;
+
+ /** @var int */
+ public $flags;
+
+ public function __construct(int $flags = self::TARGET_ALL)
+ {
+ $this->flags = $flags;
+ }
+}
diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php b/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php
new file mode 100644
index 00000000..bd1212f6
--- /dev/null
+++ b/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php
@@ -0,0 +1,16 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+if (\PHP_VERSION_ID < 80000 && extension_loaded('tokenizer')) {
+ class PhpToken extends Symfony\Polyfill\Php80\PhpToken
+ {
+ }
+}
diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php b/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php
new file mode 100644
index 00000000..7c62d750
--- /dev/null
+++ b/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php
@@ -0,0 +1,20 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+if (\PHP_VERSION_ID < 80000) {
+ interface Stringable
+ {
+ /**
+ * @return string
+ */
+ public function __toString();
+ }
+}
diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php b/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php
new file mode 100644
index 00000000..01c6c6c8
--- /dev/null
+++ b/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php
@@ -0,0 +1,16 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+if (\PHP_VERSION_ID < 80000) {
+ class UnhandledMatchError extends Error
+ {
+ }
+}
diff --git a/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php b/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php
new file mode 100644
index 00000000..783dbc28
--- /dev/null
+++ b/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php
@@ -0,0 +1,16 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+if (\PHP_VERSION_ID < 80000) {
+ class ValueError extends Error
+ {
+ }
+}
diff --git a/vendor/symfony/polyfill-php80/bootstrap.php b/vendor/symfony/polyfill-php80/bootstrap.php
new file mode 100644
index 00000000..e5f7dbc1
--- /dev/null
+++ b/vendor/symfony/polyfill-php80/bootstrap.php
@@ -0,0 +1,42 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+use Symfony\Polyfill\Php80 as p;
+
+if (\PHP_VERSION_ID >= 80000) {
+ return;
+}
+
+if (!defined('FILTER_VALIDATE_BOOL') && defined('FILTER_VALIDATE_BOOLEAN')) {
+ define('FILTER_VALIDATE_BOOL', \FILTER_VALIDATE_BOOLEAN);
+}
+
+if (!function_exists('fdiv')) {
+ function fdiv(float $num1, float $num2): float { return p\Php80::fdiv($num1, $num2); }
+}
+if (!function_exists('preg_last_error_msg')) {
+ function preg_last_error_msg(): string { return p\Php80::preg_last_error_msg(); }
+}
+if (!function_exists('str_contains')) {
+ function str_contains(?string $haystack, ?string $needle): bool { return p\Php80::str_contains($haystack ?? '', $needle ?? ''); }
+}
+if (!function_exists('str_starts_with')) {
+ function str_starts_with(?string $haystack, ?string $needle): bool { return p\Php80::str_starts_with($haystack ?? '', $needle ?? ''); }
+}
+if (!function_exists('str_ends_with')) {
+ function str_ends_with(?string $haystack, ?string $needle): bool { return p\Php80::str_ends_with($haystack ?? '', $needle ?? ''); }
+}
+if (!function_exists('get_debug_type')) {
+ function get_debug_type($value): string { return p\Php80::get_debug_type($value); }
+}
+if (!function_exists('get_resource_id')) {
+ function get_resource_id($resource): int { return p\Php80::get_resource_id($resource); }
+}
diff --git a/vendor/symfony/polyfill-php80/composer.json b/vendor/symfony/polyfill-php80/composer.json
new file mode 100644
index 00000000..f1801f40
--- /dev/null
+++ b/vendor/symfony/polyfill-php80/composer.json
@@ -0,0 +1,40 @@
+{
+ "name": "symfony/polyfill-php80",
+ "type": "library",
+ "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+ "keywords": ["polyfill", "shim", "compatibility", "portable"],
+ "homepage": "https://symfony.com",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Ion Bazan",
+ "email": "ion.bazan@gmail.com"
+ },
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "require": {
+ "php": ">=7.1"
+ },
+ "autoload": {
+ "psr-4": { "Symfony\\Polyfill\\Php80\\": "" },
+ "files": [ "bootstrap.php" ],
+ "classmap": [ "Resources/stubs" ]
+ },
+ "minimum-stability": "dev",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.28-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ }
+}
diff --git a/vendor/symfony/process/ExecutableFinder.php b/vendor/symfony/process/ExecutableFinder.php
index ff68ed33..e2dd064d 100644
--- a/vendor/symfony/process/ExecutableFinder.php
+++ b/vendor/symfony/process/ExecutableFinder.php
@@ -50,8 +50,8 @@ public function addSuffix($suffix)
*/
public function find($name, $default = null, array $extraDirs = [])
{
- if (ini_get('open_basedir')) {
- $searchPath = array_merge(explode(\PATH_SEPARATOR, ini_get('open_basedir')), $extraDirs);
+ if (\ini_get('open_basedir')) {
+ $searchPath = array_merge(explode(\PATH_SEPARATOR, \ini_get('open_basedir')), $extraDirs);
$dirs = [];
foreach ($searchPath as $path) {
// Silencing against https://bugs.php.net/69240
diff --git a/vendor/symfony/process/InputStream.php b/vendor/symfony/process/InputStream.php
index c86fca86..4f8f7133 100644
--- a/vendor/symfony/process/InputStream.php
+++ b/vendor/symfony/process/InputStream.php
@@ -69,6 +69,7 @@ public function isClosed()
/**
* @return \Traversable
*/
+ #[\ReturnTypeWillChange]
public function getIterator()
{
$this->open = true;
diff --git a/vendor/symfony/process/LICENSE b/vendor/symfony/process/LICENSE
index 9e936ec0..88bf75bb 100644
--- a/vendor/symfony/process/LICENSE
+++ b/vendor/symfony/process/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2020 Fabien Potencier
+Copyright (c) 2004-2022 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/symfony/process/PhpExecutableFinder.php b/vendor/symfony/process/PhpExecutableFinder.php
index 3d5eabd9..92e0262a 100644
--- a/vendor/symfony/process/PhpExecutableFinder.php
+++ b/vendor/symfony/process/PhpExecutableFinder.php
@@ -47,6 +47,10 @@ public function find($includeArgs = true)
}
}
+ if (@is_dir($php)) {
+ return false;
+ }
+
return $php;
}
@@ -59,7 +63,7 @@ public function find($includeArgs = true)
}
if ($php = getenv('PHP_PATH')) {
- if (!@is_executable($php)) {
+ if (!@is_executable($php) || @is_dir($php)) {
return false;
}
@@ -67,12 +71,12 @@ public function find($includeArgs = true)
}
if ($php = getenv('PHP_PEAR_PHP_BIN')) {
- if (@is_executable($php)) {
+ if (@is_executable($php) && !@is_dir($php)) {
return $php;
}
}
- if (@is_executable($php = \PHP_BINDIR.('\\' === \DIRECTORY_SEPARATOR ? '\\php.exe' : '/php'))) {
+ if (@is_executable($php = \PHP_BINDIR.('\\' === \DIRECTORY_SEPARATOR ? '\\php.exe' : '/php')) && !@is_dir($php)) {
return $php;
}
diff --git a/vendor/symfony/process/Pipes/AbstractPipes.php b/vendor/symfony/process/Pipes/AbstractPipes.php
index 6b72aed7..9532e3ef 100644
--- a/vendor/symfony/process/Pipes/AbstractPipes.php
+++ b/vendor/symfony/process/Pipes/AbstractPipes.php
@@ -47,7 +47,9 @@ public function __construct($input)
public function close()
{
foreach ($this->pipes as $pipe) {
- fclose($pipe);
+ if (\is_resource($pipe)) {
+ fclose($pipe);
+ }
}
$this->pipes = [];
}
@@ -102,7 +104,7 @@ protected function write(): ?array
stream_set_blocking($input, 0);
} elseif (!isset($this->inputBuffer[0])) {
if (!\is_string($input)) {
- if (!is_scalar($input)) {
+ if (!\is_scalar($input)) {
throw new InvalidArgumentException(sprintf('"%s" yielded a value of type "%s", but only scalars and stream resources are supported.', \get_class($this->input), \gettype($input)));
}
$input = (string) $input;
@@ -133,7 +135,7 @@ protected function write(): ?array
}
if ($input) {
- for (;;) {
+ while (true) {
$data = fread($input, self::CHUNK_SIZE);
if (!isset($data[0])) {
break;
@@ -171,7 +173,7 @@ protected function write(): ?array
/**
* @internal
*/
- public function handleError($type, $msg)
+ public function handleError(int $type, string $msg)
{
$this->lastError = $msg;
}
diff --git a/vendor/symfony/process/Pipes/UnixPipes.php b/vendor/symfony/process/Pipes/UnixPipes.php
index 70fdd295..58a8da07 100644
--- a/vendor/symfony/process/Pipes/UnixPipes.php
+++ b/vendor/symfony/process/Pipes/UnixPipes.php
@@ -35,6 +35,19 @@ public function __construct(?bool $ttyMode, bool $ptyMode, $input, bool $haveRea
parent::__construct($input);
}
+ /**
+ * @return array
+ */
+ public function __sleep()
+ {
+ throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
+ }
+
+ public function __wakeup()
+ {
+ throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
+ }
+
public function __destruct()
{
$this->close();
diff --git a/vendor/symfony/process/Pipes/WindowsPipes.php b/vendor/symfony/process/Pipes/WindowsPipes.php
index b22171dd..69768f3d 100644
--- a/vendor/symfony/process/Pipes/WindowsPipes.php
+++ b/vendor/symfony/process/Pipes/WindowsPipes.php
@@ -71,7 +71,7 @@ public function __construct($input, bool $haveReadSupport)
}
$this->lockHandles[$pipe] = $h;
- if (!fclose(fopen($file, 'w')) || !$h = fopen($file, 'r')) {
+ if (!($h = fopen($file, 'w')) || !fclose($h) || !$h = fopen($file, 'r')) {
flock($this->lockHandles[$pipe], \LOCK_UN);
fclose($this->lockHandles[$pipe]);
unset($this->lockHandles[$pipe]);
@@ -88,6 +88,19 @@ public function __construct($input, bool $haveReadSupport)
parent::__construct($input);
}
+ /**
+ * @return array
+ */
+ public function __sleep()
+ {
+ throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
+ }
+
+ public function __wakeup()
+ {
+ throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
+ }
+
public function __destruct()
{
$this->close();
diff --git a/vendor/symfony/process/Process.php b/vendor/symfony/process/Process.php
index 5f8ba6d1..09cd9602 100644
--- a/vendor/symfony/process/Process.php
+++ b/vendor/symfony/process/Process.php
@@ -53,7 +53,7 @@ class Process implements \IteratorAggregate
private $hasCallback = false;
private $commandline;
private $cwd;
- private $env;
+ private $env = [];
private $input;
private $starttime;
private $lastOutputTime;
@@ -132,7 +132,7 @@ class Process implements \IteratorAggregate
* @param array $command The command to run and its arguments listed as separate entries
* @param string|null $cwd The working directory or null to use the working dir of the current PHP process
* @param array|null $env The environment variables or null to use the same environment as the current PHP process
- * @param mixed|null $input The input as stream resource, scalar or \Traversable, or null for no input
+ * @param mixed $input The input as stream resource, scalar or \Traversable, or null for no input
* @param int|float|null $timeout The timeout in seconds or null to disable
*
* @throws LogicException When proc_open is not installed
@@ -177,13 +177,13 @@ public function __construct($command, string $cwd = null, array $env = null, $in
* In order to inject dynamic values into command-lines, we strongly recommend using placeholders.
* This will save escaping values, which is not portable nor secure anyway:
*
- * $process = Process::fromShellCommandline('my_command "$MY_VAR"');
+ * $process = Process::fromShellCommandline('my_command "${:MY_VAR}"');
* $process->run(null, ['MY_VAR' => $theValue]);
*
* @param string $command The command line to pass to the shell of the OS
* @param string|null $cwd The working directory or null to use the working dir of the current PHP process
* @param array|null $env The environment variables or null to use the same environment as the current PHP process
- * @param mixed|null $input The input as stream resource, scalar or \Traversable, or null for no input
+ * @param mixed $input The input as stream resource, scalar or \Traversable, or null for no input
* @param int|float|null $timeout The timeout in seconds or null to disable
*
* @return static
@@ -198,6 +198,19 @@ public static function fromShellCommandline(string $command, string $cwd = null,
return $process;
}
+ /**
+ * @return array
+ */
+ public function __sleep()
+ {
+ throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
+ }
+
+ public function __wakeup()
+ {
+ throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
+ }
+
public function __destruct()
{
$this->stop(0);
@@ -291,10 +304,10 @@ public function start(callable $callback = null, array $env = [])
$descriptors = $this->getDescriptors();
if ($this->env) {
- $env += $this->env;
+ $env += '\\' === \DIRECTORY_SEPARATOR ? array_diff_ukey($this->env, $env, 'strcasecmp') : $this->env;
}
- $env += $this->getDefaultEnv();
+ $env += '\\' === \DIRECTORY_SEPARATOR ? array_diff_ukey($this->getDefaultEnv(), $env, 'strcasecmp') : $this->getDefaultEnv();
if (\is_array($commandline = $this->commandline)) {
$commandline = implode(' ', array_map([$this, 'escapeArgument'], $commandline));
@@ -327,7 +340,7 @@ public function start(callable $callback = null, array $env = [])
$envPairs = [];
foreach ($env as $k => $v) {
- if (false !== $v) {
+ if (false !== $v && false === \in_array($k, ['argc', 'argv', 'ARGC', 'ARGV'], true)) {
$envPairs[] = $k.'='.$v;
}
}
@@ -609,6 +622,7 @@ public function getIncrementalOutput()
*
* @return \Generator
*/
+ #[\ReturnTypeWillChange]
public function getIterator($flags = 0)
{
$this->readPipesForOutput(__FUNCTION__, false);
@@ -758,7 +772,7 @@ public function getExitCodeText()
return null;
}
- return isset(self::$exitCodes[$exitcode]) ? self::$exitCodes[$exitcode] : 'Unknown error';
+ return self::$exitCodes[$exitcode] ?? 'Unknown error';
}
/**
@@ -959,8 +973,6 @@ public function addErrorOutput(string $line)
/**
* Gets the last output time in seconds.
- *
- * @return float|null The last output time in seconds or null if it isn't started
*/
public function getLastOutputTime(): ?float
{
@@ -1157,25 +1169,12 @@ public function getEnv()
/**
* Sets the environment variables.
*
- * Each environment variable value should be a string.
- * If it is an array, the variable is ignored.
- * If it is false or null, it will be removed when
- * env vars are otherwise inherited.
- *
- * That happens in PHP when 'argv' is registered into
- * the $_ENV array for instance.
- *
- * @param array $env The new environment variables
+ * @param array $env The new environment variables
*
* @return $this
*/
public function setEnv(array $env)
{
- // Process can not handle env values that are arrays
- $env = array_filter($env, function ($value) {
- return !\is_array($value);
- });
-
$this->env = $env;
return $this;
@@ -1385,7 +1384,7 @@ protected function isSigchildEnabled()
ob_start();
phpinfo(\INFO_GENERAL);
- return self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild');
+ return self::$sigchild = str_contains(ob_get_clean(), '--enable-sigchild');
}
/**
@@ -1487,8 +1486,8 @@ private function resetProcessData()
$this->exitcode = null;
$this->fallbackStatus = [];
$this->processInformation = null;
- $this->stdout = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+b');
- $this->stderr = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+b');
+ $this->stdout = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+');
+ $this->stderr = fopen('php://temp/maxmemory:'.(1024 * 1024), 'w+');
$this->process = null;
$this->latestSignal = null;
$this->status = self::STATUS_READY;
@@ -1502,8 +1501,6 @@ private function resetProcessData()
* @param int $signal A valid POSIX signal (see https://php.net/pcntl.constants)
* @param bool $throwException Whether to throw exception in case signal failed
*
- * @return bool True if the signal was sent successfully, false otherwise
- *
* @throws LogicException In case the process is not running
* @throws RuntimeException In case --enable-sigchild is activated and the process can't be killed
* @throws RuntimeException In case of failure
@@ -1572,7 +1569,7 @@ function ($m) use (&$env, &$varCache, &$varCount, $uid) {
if (isset($varCache[$m[0]])) {
return $varCache[$m[0]];
}
- if (false !== strpos($value = $m[1], "\0")) {
+ if (str_contains($value = $m[1], "\0")) {
$value = str_replace("\0", '?', $value);
}
if (false === strpbrk($value, "\"%!\n")) {
@@ -1633,7 +1630,7 @@ private function escapeArgument(?string $argument): string
if ('\\' !== \DIRECTORY_SEPARATOR) {
return "'".str_replace("'", "'\\''", $argument)."'";
}
- if (false !== strpos($argument, "\0")) {
+ if (str_contains($argument, "\0")) {
$argument = str_replace("\0", '?', $argument);
}
if (!preg_match('/[\/()%!^"<>&|\s]/', $argument)) {
@@ -1657,20 +1654,9 @@ private function replacePlaceholders(string $commandline, array $env)
private function getDefaultEnv(): array
{
- $env = [];
-
- foreach ($_SERVER as $k => $v) {
- if (\is_string($v) && false !== $v = getenv($k)) {
- $env[$k] = $v;
- }
- }
-
- foreach ($_ENV as $k => $v) {
- if (\is_string($v)) {
- $env[$k] = $v;
- }
- }
+ $env = getenv();
+ $env = ('\\' === \DIRECTORY_SEPARATOR ? array_intersect_ukey($env, $_SERVER, 'strcasecmp') : array_intersect_key($env, $_SERVER)) ?: $env;
- return $env;
+ return $_ENV + ('\\' === \DIRECTORY_SEPARATOR ? array_diff_ukey($env, $_ENV, 'strcasecmp') : $env);
}
}
diff --git a/vendor/symfony/process/ProcessUtils.php b/vendor/symfony/process/ProcessUtils.php
index eb39a4a9..121693ba 100644
--- a/vendor/symfony/process/ProcessUtils.php
+++ b/vendor/symfony/process/ProcessUtils.php
@@ -48,7 +48,7 @@ public static function validateInput($caller, $input)
if (\is_string($input)) {
return $input;
}
- if (is_scalar($input)) {
+ if (\is_scalar($input)) {
return (string) $input;
}
if ($input instanceof Process) {
diff --git a/vendor/symfony/process/README.md b/vendor/symfony/process/README.md
index b7ca5b42..afce5e45 100644
--- a/vendor/symfony/process/README.md
+++ b/vendor/symfony/process/README.md
@@ -6,8 +6,8 @@ The Process component executes commands in sub-processes.
Resources
---------
- * [Documentation](https://symfony.com/doc/current/components/process.html)
- * [Contributing](https://symfony.com/doc/current/contributing/index.html)
- * [Report issues](https://github.com/symfony/symfony/issues) and
- [send Pull Requests](https://github.com/symfony/symfony/pulls)
- in the [main Symfony repository](https://github.com/symfony/symfony)
+ * [Documentation](https://symfony.com/doc/current/components/process.html)
+ * [Contributing](https://symfony.com/doc/current/contributing/index.html)
+ * [Report issues](https://github.com/symfony/symfony/issues) and
+ [send Pull Requests](https://github.com/symfony/symfony/pulls)
+ in the [main Symfony repository](https://github.com/symfony/symfony)
diff --git a/vendor/symfony/process/composer.json b/vendor/symfony/process/composer.json
index 026200e8..c0f7599f 100644
--- a/vendor/symfony/process/composer.json
+++ b/vendor/symfony/process/composer.json
@@ -1,7 +1,7 @@
{
"name": "symfony/process",
"type": "library",
- "description": "Symfony Process Component",
+ "description": "Executes commands in sub-processes",
"keywords": [],
"homepage": "https://symfony.com",
"license": "MIT",
@@ -16,7 +16,8 @@
}
],
"require": {
- "php": ">=7.1.3"
+ "php": ">=7.1.3",
+ "symfony/polyfill-php80": "^1.16"
},
"autoload": {
"psr-4": { "Symfony\\Component\\Process\\": "" },
From 72d90eeeae10e6fa8c7f08cbcda00ecea1423726 Mon Sep 17 00:00:00 2001
From: DevDavido <997605+DevDavido@users.noreply.github.com>
Date: Wed, 20 Dec 2023 00:13:15 +0100
Subject: [PATCH 03/11] refactor: Provide more time until stale issue is closed
---
.github/stale.yml | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/.github/stale.yml b/.github/stale.yml
index edf7b8ac..75ccde2c 100644
--- a/.github/stale.yml
+++ b/.github/stale.yml
@@ -1,10 +1,9 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 90
# Number of days of inactivity before a stale issue is closed
-daysUntilClose: 7
+daysUntilClose: 30
# Issues with these labels will never be considered stale
exemptLabels:
- - pinned
- security
- nostale
# Label to use when marking an issue as stale
@@ -13,6 +12,6 @@ staleLabel: stale
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs
- within the next 7 days. Thank you for your contributions.
+ within the next 30 days. Thank you for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false
From 6709f7ef03874b7af6a506d7467305f743d9c348 Mon Sep 17 00:00:00 2001
From: DevDavido <997605+DevDavido@users.noreply.github.com>
Date: Wed, 20 Dec 2023 00:15:25 +0100
Subject: [PATCH 04/11] refactor: Update author information
---
README.md | 4 ++--
composer.json | 3 +--
plugin.json | 5 ++---
3 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
index d40f36d6..0028ecbc 100644
--- a/README.md
+++ b/README.md
@@ -82,10 +82,10 @@ Please see the [CHANGELOG](CHANGELOG.md) for more information on what has change
- Add support for [mobile Matomo app](https://matomo.org/mobile/).
## Contact
-If you have any questions or inquiries, you can contact `github {at} diskoboss {døt} de`.
+If you have any questions or inquiries, you can contact `github{at}diskoboss{døt}de`.
## Security
-If you discover any security related issues, please contact `github {at} diskoboss {døt} de` instead of using the issue tracker.
+If you discover any security related issues, please contact `github{at}diskoboss{døt}de` instead of using the issue tracker.
Please note that the performance audits will be performed with Chromium which renders Matomo-tracked web pages on your server without the sandbox mode of Chromium. You can find more information about this possible issue on the [lighthouse-cli repository](https://github.com/GoogleChrome/lighthouse-ci/tree/master/docs/recipes/docker-client#--no-sandbox-issues-explained).
diff --git a/composer.json b/composer.json
index 68637364..a29e5225 100644
--- a/composer.json
+++ b/composer.json
@@ -4,8 +4,7 @@
"license": "GPL-3.0-only",
"authors": [
{
- "name": "David",
- "email": "github@diskoboss.de",
+ "name": "DevDavido",
"homepage": "https://github.com/DevDavido"
}
],
diff --git a/plugin.json b/plugin.json
index 8d61a43e..8a82dfe3 100644
--- a/plugin.json
+++ b/plugin.json
@@ -9,8 +9,7 @@
},
"authors": [
{
- "name": "David",
- "email": "github@diskoboss.de",
+ "name": "DevDavido",
"homepage": "https://github.com/DevDavido"
}
],
@@ -18,7 +17,7 @@
"paypal": "david.domainemail@gmx.de"
},
"support": {
- "email": "github@diskoboss.de",
+ "email": "github{at}diskoboss{døt}de",
"issues": "https://github.com/DevDavido/performance-audit-plugin/issues"
},
"homepage": "https://github.com/DevDavido/performance-audit-plugin",
From 1acf662989ab62294e1ee8f226aa7374383e92b7 Mon Sep 17 00:00:00 2001
From: DevDavido <997605+DevDavido@users.noreply.github.com>
Date: Wed, 20 Dec 2023 00:16:54 +0100
Subject: [PATCH 05/11] refactor: Update donation information
---
.github/FUNDING.yml | 2 +-
README.md | 2 +-
lang/en.json | 2 +-
plugin.json | 3 ---
templates/version.twig | 4 ++--
5 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index 3393d081..fd5ed831 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1 +1 @@
-custom: "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=77KW4LBEYBD9U"
+custom: "https://www.buymeacoffee.com/devdavido"
diff --git a/README.md b/README.md
index 0028ecbc..3a2abde7 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ Continuously monitor those Web Vital metrics over time, allowing detection of un
## Support me
If you installed this plugin and it was useful for you or your business, please don't hesitate to make a donation, I would highly appreciate it. Thank you!
-
+
## Installation
Preferably you install [this plugin](https://plugins.matomo.org/PerformanceAudit) automatically by:
diff --git a/lang/en.json b/lang/en.json
index fade106a..aa435a50 100644
--- a/lang/en.json
+++ b/lang/en.json
@@ -5,7 +5,7 @@
"CoreAdminHome_MenuPerformance": "Performance",
"CoreAdminHome_PluginPerformance": "PerformanceAudit Plugin",
"CoreAdminHome_VersionPerformance": "You are currently using version %1$s%2$s%3$s of the %4$s plugin.",
- "Donate": "Donate",
+ "Donate_BuyMeACoffee": "Buy me a coffee",
"EnvironmentDesktop": "desktop",
"EnvironmentMobile": "mobile",
"Metrics_Max_Percent": "Highest %",
diff --git a/plugin.json b/plugin.json
index 8a82dfe3..17a8ae38 100644
--- a/plugin.json
+++ b/plugin.json
@@ -13,9 +13,6 @@
"homepage": "https://github.com/DevDavido"
}
],
- "donate": {
- "paypal": "david.domainemail@gmx.de"
- },
"support": {
"email": "github{at}diskoboss{døt}de",
"issues": "https://github.com/DevDavido/performance-audit-plugin/issues"
diff --git a/templates/version.twig b/templates/version.twig
index 9957c57a..4460f535 100644
--- a/templates/version.twig
+++ b/templates/version.twig
@@ -23,8 +23,8 @@
{{ 'PerformanceAudit_SupportMeText'|translate('
')|raw }}
-
-
+
+
From 65c2b99fc9a4f207ac8f6f73c0c1afa188ea265d Mon Sep 17 00:00:00 2001
From: DevDavido <997605+DevDavido@users.noreply.github.com>
Date: Wed, 20 Dec 2023 00:21:42 +0100
Subject: [PATCH 06/11] docs: Remove ToDo section from README
---
README.md | 3 ---
1 file changed, 3 deletions(-)
diff --git a/README.md b/README.md
index 3a2abde7..f783c3c0 100644
--- a/README.md
+++ b/README.md
@@ -78,9 +78,6 @@ Run the integration and unit tests with:
## Changelog
Please see the [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
-## ToDo
-- Add support for [mobile Matomo app](https://matomo.org/mobile/).
-
## Contact
If you have any questions or inquiries, you can contact `github{at}diskoboss{døt}de`.
From 03a6e63e2f15cc02f2390fd4e5889ad88eacf024 Mon Sep 17 00:00:00 2001
From: DevDavido <997605+DevDavido@users.noreply.github.com>
Date: Wed, 20 Dec 2023 00:21:52 +0100
Subject: [PATCH 07/11] docs: Update README badges
---
README.md | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/README.md b/README.md
index f783c3c0..fcf8695c 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,7 @@
[![Stable Version](https://img.shields.io/github/v/release/DevDavido/performance-audit-plugin)](https://github.com/DevDavido/performance-audit-plugin/releases)
[![GPL Licensed](https://img.shields.io/github/license/DevDavido/performance-audit-plugin?color=yellow)](LICENSE.md)
-[![Tests Badge](https://img.shields.io/github/workflow/status/DevDavido/performance-audit-plugin/Tests?label=tests)](https://github.com/DevDavido/performance-audit-plugin/actions?query=workflow%3ATests)
-[![Open Issues](https://img.shields.io/github/issues-raw/DevDavido/performance-audit-plugin)](https://github.com/DevDavido/performance-audit-plugin/issues)
+[![Tests Badge](https://img.shields.io/github/actions/workflow/status/DevDavido/performance-audit-plugin/tests.yml)](https://github.com/DevDavido/performance-audit-plugin/actions/workflows/tests.yml)
## Description
Daily performance audits of all your sites in Matomo for the following metrics based on Google Lighthouse:
From fdca5b2144396a540b0701cd6675e4425f34ceff Mon Sep 17 00:00:00 2001
From: DevDavido <997605+DevDavido@users.noreply.github.com>
Date: Wed, 20 Dec 2023 00:38:51 +0100
Subject: [PATCH 08/11] feat: Add support to find latest Node executable in
Plesk environment
---
ExecutableFinder.php | 31 +++++++++++++++++++++----------
1 file changed, 21 insertions(+), 10 deletions(-)
diff --git a/ExecutableFinder.php b/ExecutableFinder.php
index a1b88825..fe3e9cd6 100644
--- a/ExecutableFinder.php
+++ b/ExecutableFinder.php
@@ -36,14 +36,6 @@ public static function search($name)
return $executablePath;
}
- /*
- public static function getDefaultComposerHomePath() {
- return ExecutableFinder::isRunningOnWindows() ?
- '%HOMEDRIVE%%HOMEPATH%\AppData\Roaming\Composer' :
- '$HOME/.composer';
- }
- */
-
/**
* Get default path for executables depending on platform.
*
@@ -51,8 +43,27 @@ public static function getDefaultComposerHomePath() {
*/
public static function getDefaultPath() {
return ExecutableFinder::isRunningOnWindows() ?
- '%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;' :
- '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/plesk/node/14/bin:/opt/plesk/node/12/bin:/opt/plesk/node/10/bin';
+ implode(";", [
+ '%SystemRoot%\system32',
+ '%SystemRoot%',
+ '%SystemRoot%\System32\Wbem'
+ ]) :
+ implode(":", [
+ '/usr/local/sbin',
+ '/usr/local/bin',
+ '/usr/sbin',
+ '/usr/bin',
+ '/sbin',
+ '/bin',
+ '/opt/plesk/node/24/bin',
+ '/opt/plesk/node/22/bin',
+ '/opt/plesk/node/20/bin',
+ '/opt/plesk/node/18/bin',
+ '/opt/plesk/node/16/bin',
+ '/opt/plesk/node/14/bin',
+ '/opt/plesk/node/12/bin',
+ '/opt/plesk/node/10/bin'
+ ]);
}
/**
From f3970e1dd12d4fcf4bfd7715b3b33ed15a9efcf4 Mon Sep 17 00:00:00 2001
From: DevDavido <997605+DevDavido@users.noreply.github.com>
Date: Wed, 20 Dec 2023 00:58:26 +0100
Subject: [PATCH 09/11] build: Release 2.1.0
---
plugin.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/plugin.json b/plugin.json
index 17a8ae38..33efbf00 100644
--- a/plugin.json
+++ b/plugin.json
@@ -1,7 +1,7 @@
{
"name": "PerformanceAudit",
"description": "Daily performance audits of all your sites in Matomo.",
- "version": "2.0.0",
+ "version": "2.1.0",
"theme": false,
"require": {
"php": ">=7.2.5",
From dd455908d717849237ad932b00693ff1555efb25 Mon Sep 17 00:00:00 2001
From: DevDavido <997605+DevDavido@users.noreply.github.com>
Date: Wed, 20 Dec 2023 00:58:31 +0100
Subject: [PATCH 10/11] docs: Added release 2.1.0 to CHANGELOG
---
CHANGELOG.md | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d74fd172..22d5af47 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,11 @@
# Changelog
+## 2.1.0
+- Added: Site setting to group URLs by anchor which removes auditing duplicates of URLs which only differ in their anchors
+- Added: Support to find latest Node executable in Plesk environment
+- Added: Initial (partial) translation available for Albanian, Basque, Bokmål, Brazilian Portuguese, Bulgarian, Catalan, Chinese (Traditional), Dutch, French, German, Greek, Indonesian, Italian, Japanese, Portuguese, Spanish, Swedish, Turkish, Ukrainian
+- Updated: Bumped `symfony/process`, `ducks-project/spl-types`, `symfony/polyfill-mbstring` and `friendsofphp/php-cs-fixer` dependency version
+- Updated donation links
+
## 2.0.0
- Release stable version for Matomo 4
- Updated: Bumped `symfony/process` and `symfony/polyfill-mbstring` dependency version
From b1a3ac2a7628820a8e8a93a313aec735a6dc66b3 Mon Sep 17 00:00:00 2001
From: DevDavido <997605+DevDavido@users.noreply.github.com>
Date: Wed, 20 Dec 2023 14:59:08 +0100
Subject: [PATCH 11/11] build: Update tests workflow
---
.github/workflows/tests.yml | 76 ++++++-------------
Columns/Metrics/MaxPercent.php | 6 ++
Columns/Metrics/MaxSeconds.php | 6 ++
Columns/Metrics/MedianPercent.php | 6 ++
Columns/Metrics/MedianSeconds.php | 6 ++
Columns/Metrics/MinPercent.php | 6 ++
Columns/Metrics/MinSeconds.php | 6 ++
tests/Integration/ApiTest.php | 13 ++--
...erformanceAuditIntegrationPreparation.php} | 7 +-
tests/Unit/Metric/PercentTest.php | 13 ++--
tests/Unit/Metric/SecondsTest.php | 19 ++++-
11 files changed, 93 insertions(+), 71 deletions(-)
rename tests/Integration/{PerformanceAuditIntegrationTest.php => PerformanceAuditIntegrationPreparation.php} (97%)
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index f3b7b291..f16b7ae4 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -5,67 +5,37 @@ on:
paths-ignore:
- '*.md'
-env:
- PLUGIN_NAME: PerformanceAudit
- TEST_SUITE: PluginTests
- MYSQL_ADAPTER: PDO_MYSQL
-
jobs:
- phpunit:
+ tests:
strategy:
+ fail-fast: false
matrix:
- php-versions: ['7.1']
- #php-versions: ['7.1', '7.2', '7.3', '7.4', '8.0']
- matomo-versions: ['3.12.0', '3.14.0']
- node-version: [12.x]
- #node-version: [10.x, 12.x]
+ php: ['7.2', '7.4', '8.0', '8.3']
+ matomo-target: ['minimum_required_matomo', 'maximum_supported_matomo']
+ node: ['12.x', '20.x']
runs-on: ubuntu-latest
- name: PHPUnit with PHP ${{ matrix.php-versions }}, Node.js ${{ matrix.node-version }} and Matomo ${{ matrix.matomo-versions }}
+ permissions:
+ checks: write
+ pull-requests: write
+ contents: read
- steps:
- - uses: actions/checkout@v2
+ name: Tests w/ PHP ${{ matrix.php }}, Node.js ${{ matrix.node }}, Target Matomo '${{ matrix.matomo-target }}'
- - name: Setup PHP
- uses: shivammathur/setup-php@v2
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
with:
- php-version: ${{ matrix.php-versions }}
- extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, intl, gd, iconv
- coverage: none
- tools: composer, phpunit:7.5.20
+ lfs: true
+ persist-credentials: false
- - name: Use Node.js ${{ matrix.node-version }}
- uses: actions/setup-node@v1
+ - name: Run plugin tests
+ uses: matomo-org/github-action-tests@main
with:
- node-version: ${{ matrix.node-version }}
-
- - name: Create database
- run: |
- sudo /etc/init.d/mysql start
- mysql -u root -proot -e 'CREATE DATABASE IF NOT EXISTS matomo_tests;'
-
- - name: Clone Matomo and run plugin Tests
- # TODO
- run: |
- shopt -s extglob
- mkdir ${{ env.PLUGIN_NAME }}
- cp -R !(${{ env.PLUGIN_NAME }}) ${{ env.PLUGIN_NAME }}
- cp -R .git/ ${{ env.PLUGIN_NAME }}/
-
- git clone --config filter.lfs.smudge=true -q https://github.com/matomo-org/matomo.git matomo
- cd matomo
- git fetch --all
- git submodule update
- git checkout -f -q tags/${{ matrix.matomo-versions }}
- [ -d ./tests/travis/.git ] || sh -c "rm -rf ./tests/travis && git clone https://github.com/matomo-org/travis-scripts.git ./tests/travis"
- cd ./tests/travis
- git checkout master
- cd ../..
- [ ! -f ./tests/travis/check_plugin_compatible_with_piwik.php ] || php ./tests/travis/check_plugin_compatible_with_piwik.php "${{ env.PLUGIN_NAME }}"
- composer install --no-dev --no-progress
- rm -rf plugins/${{ env.PLUGIN_NAME }}
- mv ../${{ env.PLUGIN_NAME }} plugins
- echo './console tests:run PerformanceAudit'
- env:
- DB_PASSWORD: root
+ plugin-name: 'PerformanceAudit'
+ test-type: 'PluginTests'
+ php-version: ${{ matrix.php }}
+ matomo-test-branch: ${{ matrix.matomo-target }}
+ node-version: ${{ matrix.node }}
+ mysql-service: true
diff --git a/Columns/Metrics/MaxPercent.php b/Columns/Metrics/MaxPercent.php
index 12f95473..28ab5141 100644
--- a/Columns/Metrics/MaxPercent.php
+++ b/Columns/Metrics/MaxPercent.php
@@ -6,6 +6,7 @@
use Piwik\Metrics\Formatter;
use Piwik\Piwik;
+use TypeError;
class MaxPercent extends Max
{
@@ -35,9 +36,14 @@ public function getDocumentation()
* @param mixed $value
* @param Formatter $formatter
* @return mixed $value
+ * @throws TypeError
*/
public function format($value, Formatter $formatter)
{
+ if (!is_numeric($value)) {
+ throw new TypeError("A non-numeric value encountered");
+ }
+
return mb_substr($formatter->getPrettyPercentFromQuotient($value / 100), 0, -1);
}
}
diff --git a/Columns/Metrics/MaxSeconds.php b/Columns/Metrics/MaxSeconds.php
index 8324faeb..799d3a44 100644
--- a/Columns/Metrics/MaxSeconds.php
+++ b/Columns/Metrics/MaxSeconds.php
@@ -6,6 +6,7 @@
use Piwik\Metrics\Formatter;
use Piwik\Piwik;
+use TypeError;
class MaxSeconds extends Max
{
@@ -35,9 +36,14 @@ public function getDocumentation()
* @param mixed $value
* @param Formatter $formatter
* @return mixed $value
+ * @throws TypeError
*/
public function format($value, Formatter $formatter)
{
+ if (!is_numeric($value)) {
+ throw new TypeError("A non-numeric value encountered");
+ }
+
if ($value == 0) {
return '0.000';
}
diff --git a/Columns/Metrics/MedianPercent.php b/Columns/Metrics/MedianPercent.php
index 7599f41e..17c83e47 100644
--- a/Columns/Metrics/MedianPercent.php
+++ b/Columns/Metrics/MedianPercent.php
@@ -6,6 +6,7 @@
use Piwik\Metrics\Formatter;
use Piwik\Piwik;
+use TypeError;
class MedianPercent extends Median
{
@@ -35,9 +36,14 @@ public function getDocumentation()
* @param mixed $value
* @param Formatter $formatter
* @return mixed $value
+ * @throws TypeError
*/
public function format($value, Formatter $formatter)
{
+ if (!is_numeric($value)) {
+ throw new TypeError("A non-numeric value encountered");
+ }
+
return mb_substr($formatter->getPrettyPercentFromQuotient($value / 100), 0, -1);
}
}
diff --git a/Columns/Metrics/MedianSeconds.php b/Columns/Metrics/MedianSeconds.php
index 42d4e11b..ea468161 100644
--- a/Columns/Metrics/MedianSeconds.php
+++ b/Columns/Metrics/MedianSeconds.php
@@ -6,6 +6,7 @@
use Piwik\Metrics\Formatter;
use Piwik\Piwik;
+use TypeError;
class MedianSeconds extends Median
{
@@ -35,9 +36,14 @@ public function getDocumentation()
* @param mixed $value
* @param Formatter $formatter
* @return mixed $value
+ * @throws TypeError
*/
public function format($value, Formatter $formatter)
{
+ if (!is_numeric($value)) {
+ throw new TypeError("A non-numeric value encountered");
+ }
+
if ($value == 0) {
return '0.000';
}
diff --git a/Columns/Metrics/MinPercent.php b/Columns/Metrics/MinPercent.php
index de190fca..9a9358a5 100644
--- a/Columns/Metrics/MinPercent.php
+++ b/Columns/Metrics/MinPercent.php
@@ -6,6 +6,7 @@
use Piwik\Metrics\Formatter;
use Piwik\Piwik;
+use TypeError;
class MinPercent extends Min
{
@@ -35,9 +36,14 @@ public function getDocumentation()
* @param mixed $value
* @param Formatter $formatter
* @return mixed $value
+ * @throws TypeError
*/
public function format($value, Formatter $formatter)
{
+ if (!is_numeric($value)) {
+ throw new TypeError("A non-numeric value encountered");
+ }
+
return mb_substr($formatter->getPrettyPercentFromQuotient($value / 100), 0, -1);
}
}
diff --git a/Columns/Metrics/MinSeconds.php b/Columns/Metrics/MinSeconds.php
index 32b37278..90552144 100644
--- a/Columns/Metrics/MinSeconds.php
+++ b/Columns/Metrics/MinSeconds.php
@@ -6,6 +6,7 @@
use Piwik\Metrics\Formatter;
use Piwik\Piwik;
+use TypeError;
class MinSeconds extends Min
{
@@ -35,9 +36,14 @@ public function getDocumentation()
* @param mixed $value
* @param Formatter $formatter
* @return mixed $value
+ * @throws TypeError
*/
public function format($value, Formatter $formatter)
{
+ if (!is_numeric($value)) {
+ throw new TypeError("A non-numeric value encountered");
+ }
+
if ($value == 0) {
return '0.000';
}
diff --git a/tests/Integration/ApiTest.php b/tests/Integration/ApiTest.php
index d718612d..4e03f44f 100644
--- a/tests/Integration/ApiTest.php
+++ b/tests/Integration/ApiTest.php
@@ -9,14 +9,14 @@
use Piwik\ArchiveProcessor\Rules;
use Piwik\DataTable;
use Piwik\Date;
-use Piwik\Translate;
+use Piwik\Tests\Framework\Fixture;
/**
* @group ApiTest
* @group PerformanceAudit
* @group Plugins
*/
-class ApiTest extends PerformanceAuditIntegrationTest
+class ApiTest extends PerformanceAuditIntegrationPreparation
{
/**
* @var Date
@@ -29,15 +29,16 @@ public function setUp(): void
$this->date = Date::factory('2020-06-15');
- Translate::loadAllTranslations();
+ Fixture::loadAllTranslations();
Rules::setBrowserTriggerArchiving(true);
+
+ $this->markTestSkipped('Plugin API integration test contains SQL error and must be revisited: https://github.com/DevDavido/performance-audit-plugin/issues/47');
}
- public function tearDown()
+ public function tearDown(): void
{
+ Fixture::resetTranslations();
parent::tearDown();
-
- //Translate::reset();
}
// Site 1
diff --git a/tests/Integration/PerformanceAuditIntegrationTest.php b/tests/Integration/PerformanceAuditIntegrationPreparation.php
similarity index 97%
rename from tests/Integration/PerformanceAuditIntegrationTest.php
rename to tests/Integration/PerformanceAuditIntegrationPreparation.php
index f69ff8f5..daef1f2f 100644
--- a/tests/Integration/PerformanceAuditIntegrationTest.php
+++ b/tests/Integration/PerformanceAuditIntegrationPreparation.php
@@ -20,7 +20,7 @@
use Piwik\Tests\Framework\Fixture;
use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
-abstract class PerformanceAuditIntegrationTest extends IntegrationTestCase
+abstract class PerformanceAuditIntegrationPreparation extends IntegrationTestCase
{
const SERVER_HOST_NAME = 'localhost';
const SERVER_PORT = 80;
@@ -43,9 +43,10 @@ public function setUp(): void
// Create user
$this->addPreexistingSuperUser();
- $this->superUserTokenAuth = UsersManagerAPI::getInstance()->getTokenAuth(
+ $this->superUserTokenAuth = UsersManagerAPI::getInstance()->createAppSpecificTokenAuth(
self::TEST_SUPERUSER_LOGIN,
- md5(self::TEST_SUPERUSER_PASS)
+ self::TEST_SUPERUSER_PASS,
+ "app-specific-pwd-description"
);
// Create sites
diff --git a/tests/Unit/Metric/PercentTest.php b/tests/Unit/Metric/PercentTest.php
index c4ece8f5..c4bf4cb9 100644
--- a/tests/Unit/Metric/PercentTest.php
+++ b/tests/Unit/Metric/PercentTest.php
@@ -5,11 +5,11 @@
require PIWIK_INCLUDE_PATH . '/plugins/PerformanceAudit/vendor/autoload.php';
use PHPUnit\Framework\TestCase;
-use PHPUnit_Framework_Error_Warning;
use Piwik\Metrics\Formatter;
use Piwik\Plugins\PerformanceAudit\Columns\Metrics\MaxPercent;
use Piwik\Plugins\PerformanceAudit\Columns\Metrics\MedianPercent;
use Piwik\Plugins\PerformanceAudit\Columns\Metrics\MinPercent;
+use TypeError;
/**
* @group Metric
@@ -22,7 +22,7 @@ class PercentTest extends TestCase
/** @var Formatter */
private $formatter;
- public function setUp()
+ public function setUp(): void
{
parent::setUp();
@@ -45,11 +45,10 @@ public function test_max_median_min_percent_format_as_expected()
}
}
- /**
- * @expectedException PHPUnit_Framework_Error_Warning
- */
- public function test_max_median_min_percent_format_with_warning()
+ public function test_max_median_min_percent_format_with_exception()
{
+ $this->expectException(TypeError::class);
+
$objs = [
new MaxPercent(),
new MedianPercent(),
@@ -57,7 +56,7 @@ public function test_max_median_min_percent_format_with_warning()
];
foreach ($objs as $obj) {
- $this->assertSame('', $obj->format('test', $this->formatter));
+ $obj->format('test', $this->formatter);
}
}
}
diff --git a/tests/Unit/Metric/SecondsTest.php b/tests/Unit/Metric/SecondsTest.php
index 0291621e..305a1960 100644
--- a/tests/Unit/Metric/SecondsTest.php
+++ b/tests/Unit/Metric/SecondsTest.php
@@ -9,6 +9,7 @@
use Piwik\Plugins\PerformanceAudit\Columns\Metrics\MaxSeconds;
use Piwik\Plugins\PerformanceAudit\Columns\Metrics\MedianSeconds;
use Piwik\Plugins\PerformanceAudit\Columns\Metrics\MinSeconds;
+use TypeError;
/**
* @group Metric
@@ -21,7 +22,7 @@ class SecondsTest extends TestCase
/** @var Formatter */
private $formatter;
- public function setUp()
+ public function setUp(): void
{
parent::setUp();
@@ -42,7 +43,21 @@ public function test_max_median_min_seconds_format_as_expected()
$this->assertSame('50.125', $obj->format(50125, $this->formatter));
$this->assertSame('100', $obj->format(100000, $this->formatter));
$this->assertSame('-100.55', $obj->format(-100550, $this->formatter));
- $this->assertSame('0.000', $obj->format('test', $this->formatter));
+ }
+ }
+
+ public function test_max_median_min_seconds_format_with_exception()
+ {
+ $this->expectException(TypeError::class);
+
+ $objs = [
+ new MaxSeconds(),
+ new MedianSeconds(),
+ new MinSeconds()
+ ];
+
+ foreach ($objs as $obj) {
+ $obj->format('test', $this->formatter);
}
}
}