Skip to content

Commit 215fdb6

Browse files
authored
Merge pull request #384 from wpengine/chore-add-admin-functionality-wpgraphql-logging
chore: Created admin functionality for displaying and saving data
2 parents da1c67a + 69c15b0 commit 215fdb6

32 files changed

+2309
-14
lines changed

plugins/wpgraphql-logging/.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,11 @@ c3.php
4848

4949
# Cache
5050
phpcs-cache.json
51+
.psalm-cache/
5152
tests/_support/
5253
tests/_output/
5354
tests/_generated/
5455
tests/_data/
5556

5657
# Playwright outputs
57-
artifacts
58+
artifacts

plugins/wpgraphql-logging/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ A WPGraphQL logging plugin that provides visibility into request lifecycle to he
2323
- [Features](#features)
2424
- [Usage](#usage)
2525
- [Configuration](#configuration)
26+
- [Admin & Settings](#admin--settings)
2627
- [Extending the Functionality](#extending-the-functionality)
2728
- [Testing](#testing)
2829

@@ -59,6 +60,7 @@ wpgraphql-logging/
5960
├── docs/ # Docs for extending the plugin.
6061
├── src/ # Main plugin source code
6162
│ ├── Admin/ # Admin settings, menu, and settings page logic
63+
│ ├── Settings/ # Admin settings functionality for displaying and saving data.
6264
│ ├── Events/ # Event logging, pub/sub event manager for extending the logging.
6365
│ ├── Logging/ # Logging logic, logger service, Monolog handlers & processors
6466
│ ├── Plugin.php # Main plugin class (entry point)
@@ -110,6 +112,9 @@ The following documentation is available in the `docs/` directory:
110112
- [Logging](docs/Logging.md):
111113
Learn about the logging system, Monolog integration, handlers, processors, and how to use or extend the logger.
112114

115+
- [Admin](docs/admin.md):
116+
Learn how the admin settings page works, all available hooks, and how to add tabs/fields via actions and filters.
117+
113118
---
114119

115120

@@ -126,6 +131,10 @@ The following documentation is available in the `docs/` directory:
126131

127132
---
128133

134+
## Admin & Settings
135+
136+
See `docs/admin.md` for a full overview of the admin/settings architecture, hooks, and examples for adding tabs and fields.
137+
129138
## Testing
130139

131140
See [Testing.md](TESTING.md) for details on how to test the plugin.
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
settings_page_wpgraphql-logging #poststuff .postbox .inside h2 {
2+
font-size: 1.3em;
3+
font-weight: 600;
4+
padding-left: 0;
5+
}
6+
7+
8+
.form-table td input[type="text"] {
9+
width: calc(99% - 24px);
10+
display: inline-block;
11+
}
12+
.form-table td select {
13+
width: calc(99% - 24px);
14+
display: inline-block;
15+
}
16+
17+
.wpgraphql-logging-tooltip {
18+
position: relative;
19+
vertical-align: middle;
20+
display: inline-block;
21+
margin-right: 0.25rem;
22+
}
23+
24+
.wpgraphql-logging-tooltip .dashicons {
25+
color: #787c82;
26+
vertical-align: middle;
27+
}
28+
29+
.wpgraphql-logging-tooltip .tooltip-text.description {
30+
opacity: 0;
31+
visibility: hidden;
32+
text-align: center;
33+
color: #fff;
34+
background-color: #1d2327;
35+
border-radius: 4px;
36+
position: absolute;
37+
z-index: 1;
38+
width: 180px;
39+
padding: 0.5rem;
40+
top: 50%;
41+
transform: translateY(-50%);
42+
vertical-align: middle;
43+
margin-left: 0.25rem;
44+
transition: opacity 0.12s ease;
45+
}
46+
47+
.wpgraphql-logging-tooltip .tooltip-text::after {
48+
content: "";
49+
position: absolute;
50+
top: 0;
51+
left: -10px;
52+
border-width: 6px;
53+
border-style: solid;
54+
border-color: transparent #1d2327 transparent transparent;
55+
top: 50%;
56+
transform: translateY(-50%);
57+
}
58+
59+
.wpgraphql-logging-tooltip:hover .tooltip-text,
60+
.wpgraphql-logging-tooltip:focus-within .tooltip-text {
61+
visibility: visible;
62+
opacity: 1;
63+
}
64+
65+
.wpgraphql-logging-docs ul li {
66+
list-style-type: none;
67+
margin-left: 30px;
68+
padding-bottom: 16px;
69+
}
70+
71+
.wpgraphql-logging-docs ul li:before {
72+
content: url(../../icons/doc.svg);
73+
height: 1em;
74+
margin-left: -29px;
75+
margin-top: -2px;
76+
position: absolute;
77+
width: 0.5em;
78+
}
79+
80+
81+
.wpgraphql-logging-feature-list {
82+
list-style-type: disc;
83+
font-size: 1.1em;
84+
margin-left: 30px;
85+
padding-bottom: 16px;
86+
}
Lines changed: 3 additions & 0 deletions
Loading

plugins/wpgraphql-logging/bin/local/setup-docker-env.sh

100644100755
File mode changed.

plugins/wpgraphql-logging/composer.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,8 @@
143143
"phpstan": [
144144
"vendor/bin/phpstan analyze --ansi --memory-limit=1G"
145145
],
146-
"php:psalm": "psalm",
147-
"php:psalm:info": "psalm --show-info=true",
148-
"php:psalm:fix": "psalm --alter",
146+
"php:psalm": "psalm --output-format=text --no-progress",
147+
"php:psalm:fix": "psalm --alter --output-format=text --no-progress",
149148
"qa": "sh bin/local/run-qa.sh",
150149
"test": [
151150
"sh bin/local/run-unit-tests.sh coverage",
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
### Admin and Settings
2+
3+
This document explains how the WPGraphQL Logging admin settings UI is built and how to extend it with your own tabs and fields.
4+
5+
---
6+
7+
## Architecture Overview
8+
9+
- **Settings page entry**: `WPGraphQL\Logging\Admin\Settings_Page`
10+
- Registers the submenu page and orchestrates fields and tabs
11+
- Hooks added: `init` (init fields), `admin_menu` (page), `admin_init` (fields), `admin_enqueue_scripts` (assets)
12+
- **Menu page**: `WPGraphQL\Logging\Admin\Settings\Menu\Menu_Page`
13+
- Adds a submenu under Settings → WPGraphQL Logging (`wpgraphql-logging`)
14+
- Renders template `src/Admin/Settings/Templates/admin.php`
15+
- **Form manager**: `WPGraphQL\Logging\Admin\Settings\Settings_Form_Manager`
16+
- Registers the settings (`register_setting`) and sections/fields per tab
17+
- Sanitizes and saves values per tab; unknown fields are pruned
18+
- **Field collection**: `WPGraphQL\Logging\Admin\Settings\Fields\Settings_Field_Collection`
19+
- Holds all tabs and fields. A default `Basic_Configuration_Tab` is registered
20+
- **Tabs**: Implement `Settings_Tab_Interface` with `get_name()`, `get_label()`, `get_fields()`
21+
- **Fields**: Implement `Settings_Field_Interface` or use built-ins:
22+
- `Field\Checkbox_Field`
23+
- `Field\Text_Input_Field`
24+
- `Field\Select_Field`
25+
26+
Settings are stored in an array option. Keys are filterable:
27+
28+
- Option key: `wpgraphql_logging_settings` (filter `wpgraphql_logging_settings_group_option_key`)
29+
- Settings group: `wpgraphql_logging_settings_group` (filter `wpgraphql_logging_settings_group_settings_group`)
30+
31+
To read values at runtime, use `WPGraphQL\Logging\Admin\Settings\Logging_Settings_Service`:
32+
33+
```php
34+
use WPGraphQL\Logging\Admin\Settings\Logging_Settings_Service;
35+
36+
$settings = new Logging_Settings_Service();
37+
$enabled = $settings->get_setting('basic_configuration', 'enabled', false);
38+
```
39+
40+
---
41+
42+
## Hooks Reference (Admin)
43+
44+
- Action: `wpgraphql_logging_settings_init( Settings_Page $instance )`
45+
- Fired after the settings page is initialized
46+
- Action: `wpgraphql_logging_settings_field_collection_init( Settings_Field_Collection $collection )`
47+
- Fired after default tabs/fields are registered; primary extension point to add tabs/fields
48+
- Action: `wpgraphql_logging_settings_form_manager_init( Settings_Form_Manager $manager )`
49+
- Fired when the form manager is constructed
50+
- Filter: `wpgraphql_logging_settings_group_option_key( string $option_key )`
51+
- Change the option key used to store settings
52+
- Filter: `wpgraphql_logging_settings_group_settings_group( string $group )`
53+
- Change the settings group name used in `register_setting`
54+
55+
- Filter: `wpgraphql_logging_basic_configuration_fields( array $fields )`
56+
- Modify the default fields rendered in the `basic_configuration` tab. You can add, remove, or replace fields by returning a modified associative array of `field_id => Settings_Field_Interface`.
57+
- Example:
58+
```php
59+
use WPGraphQL\Logging\Admin\Settings\Fields\Field\Checkbox_Field;
60+
61+
add_filter('wpgraphql_logging_basic_configuration_fields', function(array $fields): array {
62+
// Add a custom toggle into the Basic Configuration tab
63+
$fields['enable_feature_x'] = new Checkbox_Field(
64+
'enable_feature_x',
65+
'basic_configuration',
66+
'Enable Feature X',
67+
'',
68+
'Turn on extra logging for Feature X.'
69+
);
70+
71+
// Optionally remove an existing field
72+
// unset($fields[ WPGraphQL\Logging\Admin\Settings\Fields\Tab\Basic_Configuration_Tab::DATA_SAMPLING ]);
73+
74+
return $fields;
75+
});
76+
```
77+
78+
Related (non-admin) hooks for context:
79+
80+
- Action: `wpgraphql_logging_init( Plugin $instance )` (plugin initialized)
81+
- Action: `wpgraphql_logging_activate` / `wpgraphql_logging_deactivate`
82+
83+
---
84+
85+
## Add a New Tab
86+
87+
Create a tab class implementing `Settings_Tab_Interface` and register it during `wpgraphql_logging_settings_field_collection_init`.
88+
89+
```php
90+
<?php
91+
namespace MyPlugin\WPGraphQLLogging;
92+
93+
use WPGraphQL\Logging\Admin\Settings\Fields\Settings_Field_Collection;
94+
use WPGraphQL\Logging\Admin\Settings\Fields\Tab\Settings_Tab_Interface;
95+
use WPGraphQL\Logging\Admin\Settings\Fields\Field\Text_Input_Field;
96+
97+
class My_Custom_Tab implements Settings_Tab_Interface {
98+
public function get_name(): string {
99+
return 'my_custom_tab';
100+
}
101+
102+
public function get_label(): string {
103+
return 'My Custom Tab';
104+
}
105+
106+
public function get_fields(): array {
107+
return [
108+
'my_setting' => new Text_Input_Field(
109+
'my_setting',
110+
$this->get_name(),
111+
'My Setting',
112+
'',
113+
'Describe what this setting does.',
114+
'e.g., value'
115+
),
116+
];
117+
}
118+
}
119+
120+
add_action('wpgraphql_logging_settings_field_collection_init', function (Settings_Field_Collection $collection): void {
121+
$collection->add_tab(new My_Custom_Tab());
122+
});
123+
```
124+
125+
Notes:
126+
127+
- `get_name()` must be a unique slug; it is used in the admin page URL (`tab` query arg) and section IDs
128+
- Fields returned by `get_fields()` must set their `tab` to this slug so they render on the tab
129+
130+
---
131+
132+
## Add a Field to an Existing Tab
133+
134+
You can add fields directly to the shared field collection. Ensure the field’s `tab` matches the target tab name.
135+
136+
```php
137+
<?php
138+
namespace MyPlugin\WPGraphQLLogging;
139+
140+
use WPGraphQL\Logging\Admin\Settings\Fields\Settings_Field_Collection;
141+
use WPGraphQL\Logging\Admin\Settings\Fields\Field\Checkbox_Field;
142+
143+
add_action('wpgraphql_logging_settings_field_collection_init', function (Settings_Field_Collection $collection): void {
144+
$collection->add_field(
145+
'enable_feature_x',
146+
new Checkbox_Field(
147+
'enable_feature_x',
148+
'basic_configuration', // target the built-in Basic Configuration tab
149+
'Enable Feature X',
150+
'',
151+
'Turn on extra logging for Feature X.'
152+
)
153+
);
154+
});
155+
```
156+
157+
Tips:
158+
159+
- Only fields present in the collection are saved; unknown keys are pruned during sanitize
160+
- Field input names follow: `{$option_key}[{$tab}][{$field_id}]`
161+
162+
---
163+
164+
## Reading/Saving Behavior
165+
166+
- Each submit saves only the current tab’s fields
167+
- Sanitization is delegated to each field via `sanitize_field($value)`
168+
- Unknown fields or tabs are ignored/pruned
169+
170+
Example of reading a value elsewhere:
171+
172+
```php
173+
use WPGraphQL\Logging\Admin\Settings\Logging_Settings_Service;
174+
175+
$settings = new Logging_Settings_Service();
176+
$thresholdSeconds = (float) $settings->get_setting('basic_configuration', 'performance_metrics', '0');
177+
```
178+
179+
---
180+
181+
## Common Use Cases
182+
183+
- Add organization-specific logging toggles (privacy, PII redaction)
184+
- Integrate with other plugins by exposing their settings under a new tab
185+
- Provide presets for log points (e.g., only log slow queries) via a custom select field
186+
187+
---
188+
189+
## Admin Page Details
190+
191+
- Menu: Settings → WPGraphQL Logging (`admin.php?page=wpgraphql-logging`)
192+
- Tabs: `admin.php?page=wpgraphql-logging&tab={tab_slug}`
193+
- Sections and fields are rendered with `do_settings_sections('wpgraphql-logging-{tab_slug}')`

plugins/wpgraphql-logging/phpcs.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@
326326

327327
<rule ref="SlevomatCodingStandard.Complexity.Cognitive">
328328
<properties>
329-
<property name="warningThreshold" value="7"/>
329+
<property name="warningThreshold" value="8"/>
330330
<property name="errorThreshold" value="10"/>
331331
</properties>
332332
</rule>

plugins/wpgraphql-logging/phpstan.neon.dist

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,7 @@ parameters:
3030
paths:
3131
- wpgraphql-logging.php
3232
- src/
33+
ignoreErrors:
34+
- identifier: empty.notAllowed
35+
-
36+
message: '#Constant WPGRAPHQL_LOGGING.* not found\.#'

plugins/wpgraphql-logging/psalm.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
findUnusedBaselineEntry="true"
99
findUnusedCode="false"
1010
phpVersion="8.1"
11+
cacheDirectory=".psalm-cache"
1112
>
1213
<projectFiles>
1314
<file name="wpgraphql-logging.php"/>

0 commit comments

Comments
 (0)