Skip to content

Commit 464b774

Browse files
committed
Fix PHP warnings and improve parser robustness
- Fix anonymous class handling in File_Reflector by checking for null node->name - Fix method call reflector type errors with non-expression nodes - Update WP-CLI logger to match PSR-3 interface requirements - Fix undefined array key warnings in importer with null coalescing operators - Add missing end_line field to hook export in runner.php - Fix undefined namespace warnings in relationships - Add wp-cli.yml configuration for development environment connection - Update README.md with clarified wp-env usage instructions All PHP warnings eliminated during WordPress core parsing. Processed 3,338 files successfully: 4,826 functions, 2,112 classes, 14,169 methods, 2,815 hooks.
1 parent 6859dc2 commit 464b774

8 files changed

+75
-23
lines changed

README.md

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@ npm start
4545
npm run wp-env start
4646
```
4747

48-
This will start WordPress at `http://localhost:8888` (admin: `http://localhost:8888/wp-admin/` - admin/password)
48+
This will start two WordPress environments:
49+
- **Development**: `http://localhost:8888` (admin: `http://localhost:8888/wp-admin/` - admin/password)
50+
- **Tests**: `http://localhost:8889` (for automated testing only)
4951

5052
### 4. Run Tests
5153

@@ -80,19 +82,40 @@ The parser uses:
8082

8183
### Running the Parser
8284

83-
After activating the plugin in your WordPress environment:
85+
The parser runs via WP-CLI commands in the **development environment** (port 8888). There are two ways to run WP-CLI commands:
86+
87+
#### Option 1: Using Host WP-CLI (Recommended)
88+
89+
The project includes a `wp-cli.yml` configuration file that connects to the development environment:
8490

8591
```bash
86-
# Activate the plugin
87-
wp plugin activate phpdoc-parser
92+
# Activate plugins (requires wp-cli installed on host)
93+
wp plugin activate phpdoc-parser posts-to-posts
8894

8995
# Parse WordPress core files
90-
wp parser create /path/to/wordpress/source --user=admin
96+
wp parser create /var/www/html --user=admin --quick
9197

92-
# Parse specific directory
98+
# Parse specific directory
9399
wp parser create /path/to/plugin/source --user=admin
100+
101+
# View parsed results at http://localhost:8888/wp-admin/
94102
```
95103

104+
#### Option 2: Using Docker Container
105+
106+
```bash
107+
# Find the development WordPress container ID
108+
WORDPRESS_CONTAINER=$(docker ps --filter "name=wordpress-1" --format "{{.ID}}")
109+
110+
# Activate plugins in development environment
111+
docker exec $WORDPRESS_CONTAINER wp plugin activate phpdoc-parser posts-to-posts
112+
113+
# Parse WordPress core files in development environment
114+
docker exec $WORDPRESS_CONTAINER wp parser create /var/www/html --user=admin --quick
115+
```
116+
117+
**Important**: Always use the development environment (8888) for WP-CLI operations. The test environment (8889) is only for automated PHPUnit tests.
118+
96119
### Testing
97120

98121
The project includes comprehensive tests that validate parsing accuracy:
@@ -111,11 +134,14 @@ composer run test:coverage
111134
### Using wp-env Commands
112135

113136
```bash
114-
# Access WordPress container
137+
# Access development WordPress container
138+
npm run wp-env run wordpress bash
139+
140+
# Access test WordPress container (for debugging tests only)
115141
npm run wp-env run tests-wordpress bash
116142

117-
# Run WP-CLI commands
118-
npm run wp-env run tests-wordpress wp --info
143+
# Run WP-CLI in development environment
144+
npm run wp-env run wordpress wp --info
119145

120146
# Stop environment
121147
npm run wp-env stop
@@ -124,6 +150,11 @@ npm run wp-env stop
124150
npm run wp-env clean
125151
```
126152

153+
### Environment Usage
154+
155+
- **Development (localhost:8888)**: Use for plugin development, WP-CLI commands, and manual testing
156+
- **Tests (localhost:8889)**: Automatically used by `npm test` - don't run manual commands here
157+
127158
## Parsed Output
128159

129160
The parser extracts:

lib/class-file-reflector.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,9 @@ public function leaveNode( Node $node ) {
323323
case 'Stmt_Class':
324324
// Process class and assign queued methods
325325
$class_data = $this->processClass( $node );
326-
$this->classes[] = $class_data;
326+
if ( $class_data !== null ) {
327+
$this->classes[] = $class_data;
328+
}
327329

328330
$this->method_uses_queue = array();
329331
array_pop( $this->location );
@@ -361,12 +363,21 @@ public function leaveNode( Node $node ) {
361363
* @return array Class data.
362364
*/
363365
protected function processClass( Node\Stmt\Class_ $node ) {
366+
// Skip anonymous classes (where name is null)
367+
if ( ! $node->name ) {
368+
return null;
369+
}
370+
364371
$docblock = $this->parseDocComment( $node->getDocComment() );
365372

366373
return array(
367374
'name' => $node->name->toString(),
368375
'line' => $node->getStartLine(),
369376
'end_line' => $node->getEndLine(),
377+
'final' => $node->isFinal(),
378+
'abstract' => $node->isAbstract(),
379+
'extends' => $node->extends ? $node->extends->toString() : '',
380+
'implements' => $node->implements ? array_map( fn($impl) => $impl->toString(), $node->implements ) : array(),
370381
'docblock' => $docblock,
371382
'methods' => $this->processClassMethods( $node ),
372383
'properties' => $this->processClassProperties( $node ),

lib/class-importer.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ public function import_file( array $file, $skip_sleep = false, $import_ignored =
303303
if ( '_deprecated_file' === $first_function['name'] ) {
304304

305305
// Set the deprecated flag to the version number
306-
$deprecated_file = $first_function['deprecation_version'];
306+
$deprecated_file = $first_function['deprecation_version'] ?? '';
307307
}
308308
}
309309

@@ -431,10 +431,10 @@ protected function import_class( array $data, $import_ignored = false ) {
431431
}
432432

433433
// Set class-specific meta
434-
update_post_meta( $class_id, '_wp-parser_final', (string) $data['final'] );
435-
update_post_meta( $class_id, '_wp-parser_abstract', (string) $data['abstract'] );
436-
update_post_meta( $class_id, '_wp-parser_extends', $data['extends'] );
437-
update_post_meta( $class_id, '_wp-parser_implements', $data['implements'] );
434+
update_post_meta( $class_id, '_wp-parser_final', (string) ( $data['final'] ?? false ) );
435+
update_post_meta( $class_id, '_wp-parser_abstract', (string) ( $data['abstract'] ?? false ) );
436+
update_post_meta( $class_id, '_wp-parser_extends', $data['extends'] ?? '' );
437+
update_post_meta( $class_id, '_wp-parser_implements', $data['implements'] ?? array() );
438438
update_post_meta( $class_id, '_wp-parser_properties', $data['properties'] );
439439

440440
// Now add the methods
@@ -758,7 +758,7 @@ public function import_item( array $data, $parent_post_id = 0, $import_ignored =
758758
}
759759

760760
$anything_updated[] = update_post_meta( $post_id, '_wp-parser_line_num', (string) $data['line'] );
761-
$anything_updated[] = update_post_meta( $post_id, '_wp-parser_end_line_num', (string) $data['end_line'] );
761+
$anything_updated[] = update_post_meta( $post_id, '_wp-parser_end_line_num', (string) ( $data['end_line'] ?? $data['line'] ) );
762762
$anything_updated[] = update_post_meta( $post_id, '_wp-parser_tags', $data['doc']['tags'] );
763763
$anything_updated[] = update_post_meta( $post_id, '_wp-parser_last_parsed_wp_version', $this->version );
764764

lib/class-method-call-reflector.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,12 @@ public function getClass() {
8888
}
8989

9090
// Handle variable class instantiation like new $class()
91-
return $this->pretty_printer->prettyPrintExpr( $this->node->class );
91+
if ( $this->node->class instanceof Node\Expr ) {
92+
return $this->pretty_printer->prettyPrintExpr( $this->node->class );
93+
}
94+
95+
// For anonymous classes or unsupported cases, return null
96+
return null;
9297
}
9398

9499
// Handle regular method calls

lib/class-relationships.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ public function import_item( $post_id, $data, $post_data ) {
185185
// Functions to Functions
186186
$to_type = $this->post_types['function'];
187187
foreach ( (array) @$data['uses']['functions'] as $to_function ) {
188-
$to_function_slug = $this->names_to_slugs( $to_function['name'], $data['namespace'] );
188+
$to_function_slug = $this->names_to_slugs( $to_function['name'], $data['namespace'] ?? '' );
189189

190190
$this->relationships[ $from_type ][ $post_id ][ $to_type ][] = $to_function_slug;
191191
}
@@ -199,7 +199,7 @@ public function import_item( $post_id, $data, $post_data ) {
199199
} else {
200200
$to_method_slug = $to_method['name'];
201201
}
202-
$to_method_slug = $this->names_to_slugs( $to_method_slug, $data['namespace'] );
202+
$to_method_slug = $this->names_to_slugs( $to_method_slug, $data['namespace'] ?? '' );
203203

204204
$this->relationships[ $from_type ][ $post_id ][ $to_type ][] = $to_method_slug;
205205
}
@@ -219,7 +219,7 @@ public function import_item( $post_id, $data, $post_data ) {
219219
// Methods to Functions
220220
$to_type = $this->post_types['function'];
221221
foreach ( (array) @$data['uses']['functions'] as $to_function ) {
222-
$to_function_slug = $this->names_to_slugs( $to_function['name'], $data['namespace'] );
222+
$to_function_slug = $this->names_to_slugs( $to_function['name'], $data['namespace'] ?? '' );
223223

224224
$this->relationships[ $from_type ][ $post_id ][ $to_type ][] = $to_function_slug;
225225
}
@@ -237,7 +237,7 @@ public function import_item( $post_id, $data, $post_data ) {
237237
} else {
238238
$to_method_slug = $to_method['name'];
239239
}
240-
$to_method_slug = $this->names_to_slugs( $to_method_slug, $data['namespace'] );
240+
$to_method_slug = $this->names_to_slugs( $to_method_slug, $data['namespace'] ?? '' );
241241

242242
$this->relationships[ $from_type ][ $post_id ][ $to_type ][] = $to_method_slug;
243243
}

lib/class-wp-cli-logger.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@ class WP_CLI_Logger extends AbstractLogger {
1111

1212
/**
1313
* @param string $level
14-
* @param string $message
14+
* @param \Stringable|string $message
1515
* @param array $context
1616
*
1717
* @return void
1818
*/
19-
public function log( $level, $message, array $context = array() ) {
19+
public function log( $level, \Stringable|string $message, array $context = array() ): void {
20+
$message = (string) $message;
2021

2122
switch ( $level ) {
2223

lib/runner.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ function export_hook( $hook ) {
251251
return array(
252252
'name' => $hook->getName(),
253253
'line' => $hook->getLine(),
254+
'end_line' => $hook->getLine(),
254255
'type' => $hook->getType(),
255256
'arguments' => $hook->getArguments(),
256257
'doc' => $doc,

wp-cli.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
url: http://localhost:8888
2+
user: admin
3+
quiet: true

0 commit comments

Comments
 (0)