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
15 changes: 8 additions & 7 deletions bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@
// phpcs:disable Generic.PHP.ForbiddenFunctions.Found

// There are no core functions to read these constants.
define('ABSPATH', './');
define('ABSPATH', '/');
define('WP_CONTENT_DIR', sprintf('%swp-content', ABSPATH));
define('WP_PLUGIN_DIR', sprintf('%s/plugins', WP_CONTENT_DIR));
define('WPMU_PLUGIN_DIR', sprintf('%s/mu-plugins', WP_CONTENT_DIR));
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', true);
define('WP_PLUGIN_DIR', './');
define('WPMU_PLUGIN_DIR', './');
define('EMPTY_TRASH_DAYS', 30 * 86400);
define('WP_DEBUG_DISPLAY', false);
define('EMPTY_TRASH_DAYS', 30);
define('SCRIPT_DEBUG', false);
define('WP_LANG_DIR', './');
define('WP_CONTENT_DIR', './');
define('WP_LANG_DIR', sprintf('%s/languages', WP_CONTENT_DIR));
define('COOKIE_DOMAIN', '');

// Constants for expressing human-readable intervals.
define('MINUTE_IN_SECONDS', 60);
Expand Down
17 changes: 16 additions & 1 deletion extension.neon
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,26 @@ parameters:
- ../../php-stubs/wordpress-stubs/wordpress-stubs.php
- bootstrap.php
dynamicConstantNames:
# Debug constants
- WP_DEBUG
- WP_DEBUG_LOG
- WP_DEBUG_DISPLAY
- EMPTY_TRASH_DAYS
# Directory constants
- ABSPATH
- WP_PLUGIN_DIR
- WP_LANG_DIR
- WP_CONTENT_DIR
- WPMU_PLUGIN_DIR
# Templating constants
- WP_DEFAULT_THEME
# Filesystem constants
- FS_CONNECT_TIMEOUT
- FS_TIMEOUT
- FS_CHMOD_DIR
- FS_CHMOD_FILE
# Other constants
- COOKIE_DOMAIN
- EMPTY_TRASH_DAYS
- SCRIPT_DEBUG
earlyTerminatingFunctionCalls:
- wp_send_json
Expand Down
2 changes: 2 additions & 0 deletions phpcs.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<file>tests/</file>

<exclude-pattern>tests/data/*</exclude-pattern>
<exclude-pattern>tests/phpstan-data/*</exclude-pattern>
<exclude-pattern>tests/functions.php</exclude-pattern>
<exclude-pattern>tests/WP_UnitTestCase_Base.php</exclude-pattern>

Expand All @@ -19,6 +20,7 @@
<rule ref="NeutronStandard.Functions.TypeHint.UnusedReturnType">
<exclude-pattern>tests/AssertMethodTypeSpecifyingExtensionTest.php</exclude-pattern>
<exclude-pattern>tests/DynamicReturnTypeExtensionTest.php</exclude-pattern>
<exclude-pattern>tests/DynamicConstantTypeTest.php</exclude-pattern>
</rule>

<!-- Allow string concatenation in tests -->
Expand Down
1 change: 1 addition & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
includes:
- vendor/phpstan/phpstan/conf/bleedingEdge.neon
- vendor/phpstan/phpstan-strict-rules/rules.neon
- vendor/szepeviktor/phpstan-wordpress/extension.neon
parameters:
level: 9
scanFiles:
Expand Down
30 changes: 30 additions & 0 deletions tests/DynamicConstantTypeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace SzepeViktor\PHPStan\WordPress\Tests;

class DynamicConstantTypeTest extends \PHPStan\Testing\TypeInferenceTestCase
{
/**
* @return iterable<mixed>
*/
public function dataFileAsserts(): iterable
{
yield from self::gatherAssertTypes(__DIR__ . '/data/dynamic-constants.php');
}

/**
* @dataProvider dataFileAsserts
* @param array<string> ...$args
*/
public function testFileAsserts(string $assertType, string $file, ...$args): void
{
$this->assertFileAsserts($assertType, $file, ...$args);
}

public static function getAdditionalConfigFiles(): array
{
return [dirname(__DIR__) . '/vendor/szepeviktor/phpstan-wordpress/extension.neon'];
}
}
128 changes: 128 additions & 0 deletions tests/data/dynamic-constants.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?php

declare(strict_types=1);

namespace SzepeViktor\PHPStan\WordPress\Tests;

use const ABSPATH;
use const WP_CONTENT_DIR;
use const WP_LANG_DIR;
use const WPMU_PLUGIN_DIR;
use const WP_PLUGIN_DIR;
use const WP_DEBUG;
use const WP_DEBUG_DISPLAY;
use const EMPTY_TRASH_DAYS;
use const SCRIPT_DEBUG;
use const COOKIE_DOMAIN;
use const WP_DEFAULT_THEME;
use const MINUTE_IN_SECONDS;
use const HOUR_IN_SECONDS;
use const DAY_IN_SECONDS;
use const WEEK_IN_SECONDS;
use const MONTH_IN_SECONDS;
use const YEAR_IN_SECONDS;
use const KB_IN_BYTES;
use const MB_IN_BYTES;
use const GB_IN_BYTES;
use const TB_IN_BYTES;
use const PB_IN_BYTES;
use const EB_IN_BYTES;
use const OBJECT;
use const OBJECT_K;
use const ARRAY_A;
use const ARRAY_N;
use const EP_NONE;
use const EP_PERMALINK;
use const EP_ATTACHMENT;
use const EP_DATE;
use const EP_YEAR;
use const EP_MONTH;
use const EP_DAY;
use const EP_ROOT;
use const EP_COMMENTS;
use const EP_SEARCH;
use const EP_CATEGORIES;
use const EP_TAGS;
use const EP_AUTHORS;
use const EP_PAGES;
use const EP_ALL_ARCHIVES;
use const EP_ALL;
use const FS_CONNECT_TIMEOUT;
use const FS_TIMEOUT;
use const FS_CHMOD_DIR;
use const FS_CHMOD_FILE;

use function PHPStan\Testing\assertType;

/*
* Unconditional constants resolve to constant values and are
* - defined in bootstrap.php
* - NOT part of the dynamicConstantNames list in extension.neon.
*/

assertType('60', MINUTE_IN_SECONDS);
assertType('3600', HOUR_IN_SECONDS);
assertType('86400', DAY_IN_SECONDS);
assertType('604800', WEEK_IN_SECONDS);
assertType('2592000', MONTH_IN_SECONDS);
assertType('31536000', YEAR_IN_SECONDS);

assertType('1024', KB_IN_BYTES);
assertType('1048576', MB_IN_BYTES);
assertType('1073741824', GB_IN_BYTES);

if (PHP_INT_SIZE === 8) {
// 64bit
assertType('1099511627776', TB_IN_BYTES);
assertType('1125899906842624', PB_IN_BYTES);
assertType('1152921504606846976', EB_IN_BYTES);
// ZB_IN_BYTES and YB_IN_BYTES will be converted to floats.
}

assertType("'OBJECT'", OBJECT);
assertType("'OBJECT_K'", OBJECT_K);
assertType("'ARRAY_A'", ARRAY_A);
assertType("'ARRAY_N'", ARRAY_N);

assertType('0', EP_NONE);
assertType('1', EP_PERMALINK);
assertType('2', EP_ATTACHMENT);
assertType('4', EP_DATE);
assertType('8', EP_YEAR);
assertType('16', EP_MONTH);
assertType('32', EP_DAY);
assertType('64', EP_ROOT);
assertType('128', EP_COMMENTS);
assertType('256', EP_SEARCH);
assertType('512', EP_CATEGORIES);
assertType('1024', EP_TAGS);
assertType('2048', EP_AUTHORS);
assertType('4096', EP_PAGES);
assertType('3644', EP_ALL_ARCHIVES);
assertType('8191', EP_ALL);

/*
* Conditional constants resolve to non constant types and are
* - defined in bootstrap.php
* - part of the dynamicConstantNames list in extension.neon.
*/

assertType('bool', WP_DEBUG);
// assertType('bool|string', WP_DEBUG_LOG); // PHPStan does not yet support more than one type for constants
assertType('bool', WP_DEBUG_DISPLAY);

assertType('string', ABSPATH);
assertType('string', WP_CONTENT_DIR);
assertType('string', WP_PLUGIN_DIR);
assertType('string', WPMU_PLUGIN_DIR);
assertType('string', WP_LANG_DIR);

assertType('int', FS_CONNECT_TIMEOUT);
assertType('int', FS_TIMEOUT);
assertType('int', FS_CHMOD_DIR);
assertType('int', FS_CHMOD_FILE);

assertType('string', COOKIE_DOMAIN);
assertType('int', EMPTY_TRASH_DAYS);
assertType('bool', SCRIPT_DEBUG);
assertType('string', WP_DEFAULT_THEME);
112 changes: 112 additions & 0 deletions tests/phpstan-data/dynamic-constants.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php

declare(strict_types=1);

namespace SzepeViktor\PHPStan\WordPress\Tests;

// These should not be reported as errors by PHPStan's ConstantRule
use const ABSPATH;
use const WP_CONTENT_DIR;
use const WP_LANG_DIR;
use const WPMU_PLUGIN_DIR;
use const WP_PLUGIN_DIR;
use const WP_DEBUG;
use const WP_DEBUG_LOG;
use const WP_DEBUG_DISPLAY;
use const EMPTY_TRASH_DAYS;
use const SCRIPT_DEBUG;
use const COOKIE_DOMAIN;
use const WP_DEFAULT_THEME;
use const MINUTE_IN_SECONDS;
use const HOUR_IN_SECONDS;
use const DAY_IN_SECONDS;
use const WEEK_IN_SECONDS;
use const MONTH_IN_SECONDS;
use const YEAR_IN_SECONDS;
use const KB_IN_BYTES;
use const MB_IN_BYTES;
use const GB_IN_BYTES;
use const TB_IN_BYTES;
use const PB_IN_BYTES;
use const EB_IN_BYTES;
use const OBJECT;
use const OBJECT_K;
use const ARRAY_A;
use const ARRAY_N;
use const EP_NONE;
use const EP_PERMALINK;
use const EP_ATTACHMENT;
use const EP_DATE;
use const EP_YEAR;
use const EP_MONTH;
use const EP_DAY;
use const EP_ROOT;
use const EP_COMMENTS;
use const EP_SEARCH;
use const EP_CATEGORIES;
use const EP_TAGS;
use const EP_AUTHORS;
use const EP_PAGES;
use const EP_ALL_ARCHIVES;
use const EP_ALL;
use const FS_CONNECT_TIMEOUT;
use const FS_TIMEOUT;
use const FS_CHMOD_DIR;
use const FS_CHMOD_FILE;

// These should not be reported as errors by PHPStan's ConstantRule and RequireFileExistsRule
require_once ABSPATH . 'file.php';
require_once WP_PLUGIN_DIR . '/file.php';
require_once WP_CONTENT_DIR . '/file.php';
require_once WP_LANG_DIR . '/file.php';
require_once WPMU_PLUGIN_DIR . '/file.php';

// These should not be reported as errors by PHPStan's ConstantRule
$testVariable = ABSPATH;
$testVariable = WP_CONTENT_DIR;
$testVariable = WP_LANG_DIR;
$testVariable = WPMU_PLUGIN_DIR;
$testVariable = WP_PLUGIN_DIR;
$testVariable = WP_DEBUG_LOG;
$testVariable = WP_DEBUG;
$testVariable = WP_DEBUG_DISPLAY;
$testVariable = WP_DEFAULT_THEME;
$testVariable = EMPTY_TRASH_DAYS;
$testVariable = SCRIPT_DEBUG;
$testVariable = COOKIE_DOMAIN;
$testVariable = MINUTE_IN_SECONDS;
$testVariable = HOUR_IN_SECONDS;
$testVariable = DAY_IN_SECONDS;
$testVariable = WEEK_IN_SECONDS;
$testVariable = MONTH_IN_SECONDS;
$testVariable = YEAR_IN_SECONDS;
$testVariable = KB_IN_BYTES;
$testVariable = MB_IN_BYTES;
$testVariable = GB_IN_BYTES;
$testVariable = TB_IN_BYTES;
$testVariable = PB_IN_BYTES;
$testVariable = EB_IN_BYTES;
$testVariable = OBJECT;
$testVariable = OBJECT_K;
$testVariable = ARRAY_A;
$testVariable = ARRAY_N;
$testVariable = EP_NONE;
$testVariable = EP_PERMALINK;
$testVariable = EP_ATTACHMENT;
$testVariable = EP_DATE;
$testVariable = EP_YEAR;
$testVariable = EP_MONTH;
$testVariable = EP_DAY;
$testVariable = EP_ROOT;
$testVariable = EP_COMMENTS;
$testVariable = EP_SEARCH;
$testVariable = EP_CATEGORIES;
$testVariable = EP_TAGS;
$testVariable = EP_AUTHORS;
$testVariable = EP_PAGES;
$testVariable = EP_ALL_ARCHIVES;
$testVariable = EP_ALL;
$testVariable = FS_CONNECT_TIMEOUT;
$testVariable = FS_TIMEOUT;
$testVariable = FS_CHMOD_DIR;
$testVariable = FS_CHMOD_FILE;