Skip to content

Commit 97ffa51

Browse files
committed
Initial
1 parent fafb61b commit 97ffa51

File tree

4 files changed

+185
-0
lines changed

4 files changed

+185
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/vendor/
2+
/composer.lock

composer.json

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"name": "szepeviktor/site-health-command",
3+
"description": "Check critical values in your WordPress installation",
4+
"type": "wp-cli-package",
5+
"require": {
6+
"php": ">=7.4",
7+
"wp-cli/wp-cli": "^2.0"
8+
},
9+
"require-dev": {
10+
"szepeviktor/phpcs-psr-12-neutron-hybrid-ruleset": "^1.1",
11+
"wp-coding-standards/wpcs": "3.1.0 as 2.3.0"
12+
},
13+
"license": "MIT",
14+
"autoload": {
15+
"psr-4": {
16+
"SzepeViktor\\WP_CLI\\SiteHealth\\": "src/"
17+
}
18+
},
19+
"authors": [
20+
{
21+
"name": "Viktor Szépe",
22+
"email": "viktor@szepe.net"
23+
}
24+
],
25+
"config": {
26+
"allow-plugins": {
27+
"dealerdirect/phpcodesniffer-composer-installer": true
28+
}
29+
}
30+
}

site-health-command.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
if (! class_exists('WP_CLI')) {
6+
return;
7+
}
8+
9+
require_once __DIR__ . '/vendor/autoload.php';
10+
11+
WP_CLI::add_command('site-health', 'SzepeViktor\\WP_CLI\\SiteHealth\\Command');

src/Command.php

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace SzepeViktor\WP_CLI\SiteHealth;
6+
7+
use Mustangostang\Spyc;
8+
use WP_CLI;
9+
use WP_CLI_Command;
10+
11+
use function get_option;
12+
13+
class Command extends WP_CLI_Command
14+
{
15+
/**
16+
* Checks critical site health values from a YAML file.
17+
*
18+
* ## OPTIONS
19+
*
20+
* <yaml-file>
21+
* : Path to the critical-site-health YAML file.
22+
*
23+
* ## EXAMPLES
24+
*
25+
* wp critical-site-health check /path/to/critical-site-health.yml
26+
*
27+
* @when after_wp_load
28+
*/
29+
public function check($args, $assocArgs)
30+
{
31+
$yamlPath = $args[0];
32+
33+
if (! file_exists($yamlPath)) {
34+
WP_CLI::error('YAML file not found at: ' . $yamlPath);
35+
}
36+
37+
try {
38+
$checks = Spyc::YAMLLoad($yamlPath);
39+
} catch (\Throwable $e) {
40+
WP_CLI::error('Failed to parse YAML: ' . $e->getMessage());
41+
}
42+
43+
$hadWarning = false;
44+
45+
// Option values
46+
if (isset($checks['option'])) {
47+
foreach ($checks['option'] as $option => $expected) {
48+
$actual = get_option($option);
49+
if ($actual === $expected) {
50+
continue;
51+
}
52+
53+
WP_CLI::warning("Option '$option': expected '$expected', got '$actual'");
54+
$hadWarning = true;
55+
}
56+
}
57+
58+
// Global constants
59+
if (isset($checks['global_constant'])) {
60+
foreach ($checks['global_constant'] as $name => $expected) {
61+
if (! defined($name)) {
62+
WP_CLI::warning("Constant '$name' is not defined.");
63+
$hadWarning = true;
64+
continue;
65+
}
66+
67+
$actual = constant($name);
68+
if ($actual === $expected) {
69+
continue;
70+
}
71+
72+
WP_CLI::warning("Constant '$name': expected '$expected', got '$actual'");
73+
$hadWarning = true;
74+
}
75+
}
76+
77+
// Class constants
78+
if (isset($checks['class_constant']) && is_array($checks['class_constant'])) {
79+
foreach ($checks['class_constant'] as $const => $expected) {
80+
if (! defined($const)) {
81+
WP_CLI::warning("Class constant '$const' is not defined.");
82+
$hadWarning = true;
83+
continue;
84+
}
85+
86+
$actual = constant($const);
87+
if ($actual === $expected) {
88+
continue;
89+
}
90+
91+
WP_CLI::warning("Class constant '$const': expected '$expected', got '$actual'");
92+
$hadWarning = true;
93+
}
94+
}
95+
96+
// Class methods
97+
if (isset($checks['class_method']) && is_array($checks['class_method'])) {
98+
foreach ($checks['class_method'] as $callable => $expected) {
99+
if (! is_callable($callable)) {
100+
WP_CLI::warning("Method '$callable' is not callable.");
101+
$hadWarning = true;
102+
continue;
103+
}
104+
105+
try {
106+
// phpcs:disable NeutronStandard.Functions.DisallowCallUserFunc.CallUserFunc
107+
$actual = call_user_func($callable);
108+
if ($actual !== $expected) {
109+
WP_CLI::warning("Method '$callable': expected '$expected', got '$actual'");
110+
$hadWarning = true;
111+
}
112+
} catch (\Throwable $e) {
113+
WP_CLI::warning("Method '$callable' failed: " . $e->getMessage());
114+
$hadWarning = true;
115+
}
116+
}
117+
}
118+
119+
// Eval expressions
120+
if (isset($checks['eval']) && is_array($checks['eval'])) {
121+
foreach ($checks['eval'] as $expr) {
122+
try {
123+
// phpcs:disable Generic.PHP.ForbiddenFunctions.Found,Squiz.PHP.Eval.Discouraged
124+
$result = eval(sprintf('return %s;', $expr));
125+
if ($result !== true) {
126+
WP_CLI::warning("Eval failed: '$expr' returned '$result'");
127+
$hadWarning = true;
128+
}
129+
} catch (\ParseError $e) {
130+
WP_CLI::warning('Eval error: ' . $e->getMessage());
131+
$hadWarning = true;
132+
}
133+
}
134+
}
135+
136+
if ($hadWarning) {
137+
WP_CLI::error('Health check completed with warnings.');
138+
}
139+
140+
WP_CLI::success('Critical site health checks passed.');
141+
}
142+
}

0 commit comments

Comments
 (0)